當前位置:首頁 » 網頁前端 » 前端頁面不超過可視區域
擴展閱讀
webinf下怎麼引入js 2023-08-31 21:54:13
堡壘機怎麼打開web 2023-08-31 21:54:11

前端頁面不超過可視區域

發布時間: 2023-02-05 12:51:08

A. 前端性能優化總結(一)-js、css優化

移動互聯網時代,用戶對於網頁的打開速度要求越來越高。首屏作為直面用戶的第一屏,其重要性不言而喻。優化用戶體驗更是我們前端開發非常需要 focus 的東西之一。

從用戶的角度而言,當打開一個網頁,往往關心的是從輸入完網頁地址後到最後展現完整頁面這個過程需要的時間,這個時間越短,用戶體驗越好。所以作為網頁的開發者,就從輸入url到頁面渲染呈現這個過程中去提升網頁的性能。

所以輸入URL後發生了什麼呢?在瀏覽器中輸入url會經歷域名解析、建立TCP連接、發送http請求、資源解析等步驟。

http緩存優化是網頁性能優化的重要一環,這一部分我會在後續筆記中做一個詳細總結,所以本文暫不多做詳細整理。本文主要從網頁渲染過程、網頁交互以及Vue應用優化三個角度對性能優化做一個小結。

首先談談拿到服務端資源後瀏覽器渲染的流程:

關鍵渲染路徑是瀏覽器將 HTML、CSS、JavaScript 轉換為在屏幕上呈現的像素內容所經歷的一系列步驟。也就是我們剛剛提到的的的瀏覽器渲染流程。

為盡快完成首次渲染,我們需要最大限度減小以下三種可變因素:

首先,DOM 和 CSSOM 通常是並行構建的,所以 CSS 載入不會阻塞 DOM 的解析。

然而,由於 Render Tree 是依賴於 DOM Tree 和 CSSOM Tree 的,
所以他必須等待到 CSSOM Tree 構建完成,也就是 CSS 資源載入完成(或者 CSS 資源載入失敗)後,才能開始渲染。因此,CSS 載入會阻塞 Dom 的渲染。

由此可見,對於 CSSOM 縮小、壓縮以及緩存同樣重要,我們可以從這方面考慮去優化。

當瀏覽器遇到 script 標記時,會阻止解析器繼續操作,直到 CSSOM 構建完畢,JavaScript 才會運行並繼續完成 DOM 構建過程。

當頁面中元素樣式的改變並不影響它在文檔流中的位置時(例如:color、background-color、visibility 等),瀏覽器會將新樣式賦予給元素並重新繪制它,這個過程稱為重繪。

迴流(Reflow)
當 Render Tree 中部分或全部元素的尺寸、結構、或某些屬性發生改變時,瀏覽器重新渲染部分或全部文檔的過程稱為迴流。

有時即使僅僅迴流一個單一的元素,它的父元素以及任何跟隨它的元素也會產生迴流。現代瀏覽器會對頻繁的迴流或重繪操作進行優化:瀏覽器會維護一個隊列,把所有引起迴流和重繪的操作放入隊列中,如果隊列中的任務數量或者時間間隔達到一個閾值的,瀏覽器就會將隊列清空,進行一次批處理,這樣可以把多次迴流和重繪變成一次。
當你訪問以下屬性或方法時,瀏覽器會立刻清空隊列:

因為隊列中可能會有影響到這些屬性或方法返回值的操作,即使你希望獲取的信息與隊列中操作引發的改變無關,瀏覽器也會強行清空隊列,確保你拿到的值是最精確的。

避免頻繁操作樣式,最好一次性重寫 style 屬性,或者將樣式列表定義為 class 並一次性更改 class 屬性。

避免頻繁操作 DOM,創建一個 documentFragment,在它上面應用所有 DOM 操作,最後再把它添加到文檔中。
也可以先為元素設置 display: none,操作結束後再把它顯示出來。因為在 display 屬性為 none 的元素上進行的 DOM 操作不會引發迴流和重繪。
避免頻繁讀取會引發迴流/重繪的屬性,如果確實需要多次使用,就用一個變數緩存起來。
對具有復雜動畫的元素使用絕對定位,使它脫離文檔流,否則會引起父元素及後續元素頻繁迴流。

圖片懶載入在一些圖片密集型的網站中運用比較多,通過圖片懶載入可以讓一些不可視的圖片不去載入,避免一次性載入過多的圖片導致請求阻塞(瀏覽器一般對同一域名下的並發請求的連接數有限制),這樣就可以提高網站的載入速度,提高用戶體驗。

將頁面中的img標簽src指向一張小圖片或者src為空,然後定義data-src(這個屬性可以自定義命名,我才用data-src)屬性指向真實的圖片。src指向一張默認的圖片,否則當src為空時也會向伺服器發送一次請求。可以指向loading的地址。注意,圖片要指定寬高。

當載入頁面時,先把可視區域內的img標簽的data-src屬性值負給src,然後監聽滾動事件,把用戶即將看到的圖片載入。這樣便實現了懶載入。

事件委託其實就是利用JS事件冒泡機制把原本需要綁定在子元素的響應事件(click、keydown……)委託給父元素,讓父元素擔當事件監聽的職務。事件代理的原理是DOM元素的事件冒泡。
優點:

例如有一個列表需要綁定點擊事件,每一個列表項的點擊都需要返回不同的結果。
傳統寫法:

傳統方法會利用for循環遍歷列表為每一個列表元素綁定點擊事件,當列表中元素數量非常龐大時,需要綁定大量的點擊事件,這種方式就會產生性能問題。這種情況下利用事件委託就能很好的解決這個問題。

改用事件委託:

輸入搜索時,可以用防抖debounce等優化方式,減少http請求;
這里以滾動條事件舉例:防抖函數 onscroll 結束時觸發一次,延遲執行

節流函數:只允許一個函數在N秒內執行一次。滾動條調用介面時,可以用節流throttle等優化方式,減少http請求;
下面還是一個簡單的滾動條事件節流函數:節流函數 onscroll 時,每隔一段時間觸發一次,像水滴一樣

參考鏈接: https://zhuanlan.hu.com/p/113864878?from_voters_page=true

B. 前端通用組件設計

調用組件庫的API相信很多人都會用,但是如何封裝一個高復用的組件並不是每個人都能做到,而這也是檢驗一個前端開發人員的一個標准。

說到開發組件,首先需要考慮一個問題,一個可復用的組件都需要具備哪些必要條件。

1. 細粒度考量
看過設計模式的朋友應該有了解過很多設計原則,其中一個就是 單一職責原則 ,這個原則放在開發組件中也同樣適用。在原則上一個組件就只負責一件事,這就是單一原則所帶來的好處也非常明顯,就是可以更大可能的復用組件。但如果職責過於單一,也會造成組件碎片化嚴重,過於抽象。

因此我們需要考慮,所謂的單一職責原則是建立在可復用的基礎上的。否則,可以做為獨立組件的內部組件進行使用。

2. 組件通用性考量
組件設計之初是為了當時的頁面設計進行封裝設計的,那麼之後的頁面設計極大可能是與之前不同的,那麼之前設計的組件就不能用了。

而一旦發生這樣的情況,就說明我們之前所設計的組件是不通用的,需要重新設計了。就像Antd組件庫那樣,預留了dropdownRender進行組件渲染。

通用性的設計就代表著將放棄對DOM的操作權,暴露給開發者進行操作,組件開發者本身只負責底層邏輯和基本的DOM結構。這也是開發通用型組件的秘訣之一。

3. 技術選型
css存在著許多的弊端,例如樣式易沖突(沒有作用域的概念)、書寫繁瑣(不支持嵌套)、缺少變數(不便於一件更換主題)等等。而解決這些問題的方案也是層出不窮,從最早的css預處理,到後來的Postcss,再到後來的styled-compontent,各種方式任君選擇。

4. 打包工具
產品的設計思想固然是核心,但是也需要一堆輔助工具來來幫助我們開發,例如編譯工具、測試工具、打包工具。

說到打包工具,就不得不提一下如今非常火爆的,需要配置工程師專門配置的webpack了。但是他也有一個強大的競爭對手 rollup。

rollup更適合用於組件庫的打包,優勢如下:

設計一個輪播圖組件
學以致用,學了就肯定要實踐一下。輪播圖是一個比較常見的組件,每個組件庫中都封裝的有,接下來我們也來介紹一下如何設計一個輪播圖組件。

1. 輪播圖原理
通常情況下我們使用輪播圖是這樣編寫的

那麼為什麼放入了四個div盒子卻只顯示一個呢,這是因為可視區域是固定的,只需要移動div盒子就可以顯示出後面的盒子,這樣就達到了輪播的效果。

為了是觀看效果更好,我們都會隱藏掉可視區域之外的內容,這樣就是大家經常看到的輪播圖了。組件就可以這樣設計:

可以通過transform: translateX()不斷改變SlideList的位置,就可以達到輪播的效果了。

2. 輪播圖的基礎實現
知道了基礎原理就可以進行組件的實現了,這里以移動端輪播圖為例。

首先,獲取移動端可視窗口的寬度。

------- 未完待續 --------

C. 這種前端頁面效果是如何實現的請大神指教。

用CSS3和JS,或者單用JS也可以,原理就是監測元素到窗口的距離,當元素距窗口達到指定距離時,添加或刪除相應的CSS,讓元素移動,當然,JS也可以

D. 手機前端頁面尺寸

iPhone手機網頁的設計尺寸

iPhone5尺寸是640x1136px解析度是326PPI

iPhone4和iPhone4S尺寸是640x960px解析度是326PPI

iPhone和iPodTouch第一代、第二代、第三代尺寸是320x480px解析度是163PPI

安卓網頁的設計尺寸

320dp:一個普通的手機屏幕(240X320,320×480,480X800)

480dp:一個中間平板電腦像(480×800)

600dp:7寸平板電腦(600×1024)

720dp:10寸平板電腦(720×1280,800×1280)

ipad網頁的設計尺寸

iPad第三代第四代尺寸是2048x1536px解析度是264PPI

iPad第一代第二代尺寸是1024x768px解析度是132PPI

iPad Mini尺寸是1024x768px解析度是163PPI

以上是移動端的尺寸,單獨的如果某一個移動的網站的尺寸是沒有的,因為移動網站的一半情況是按照%比的尺寸 來自動適應屏幕的大小,或者也通過設置,iphone執行什麼尺寸,安卓情況執行什麼尺寸的。

E. 手機前端頁面尺寸

iPhone4/iPhone4s 320 * 372 / 320 * 441 (已隱藏URL與狀態欄)

iPhone5/iPhone5s 320 * 460 / 320 * 529 (已隱藏URL與狀態欄)

Note2 360 * 567 (未隱藏URL與狀態欄)

iPad 3/4 768*928 (未隱藏URL與狀態欄)

GALAXY SIII 360 * 567 (未隱藏URL與狀態欄)

小米2A 360 *567 (未隱藏URL與狀態欄)
HTC G10 320 * 460

<meta name="viewport"

網頁手機wap2.0網頁的head里加入下面這條元標簽,在iPhone的瀏覽器中頁面將以原始大小顯示,並不允許縮放。
<meta name="viewport"
content="width=device-width, initial-scale=1.0, minimum-scale=1.0,
maximum-scale=1.0,
user-scalable=no">

width - viewport的寬度 height -
viewport的高度

initial-scale - 初始的縮放比例
minimum-scale -
允許用戶縮放到的最小比例

maximum-scale -
允許用戶縮放到的最大比例
user-scalable - 用戶是否可以手動縮放

參考:

一、網頁手機wap2.0網頁的head里加入下面這條元標簽,在iPhone的瀏覽器中頁面將以原始大小顯示,並不允許縮放。

<meta name="viewport"
content="width=device-width,
initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0,
user-scalable=no">

其中: width - viewport的寬度 height - viewport的高度 initial-scale -
初始的縮放比例
minimum-scale - 允許用戶縮放到的最小比例 maximum-scale - 允許用戶縮放到的最大比例
user-scalable -
用戶是否可以手動縮放c

二、關於meta的詳細介紹請參考

三、下文是關於Meta的例子的詳細介紹 原文地址

3. Meta元素可視區

默認情況下,iPhone上的Safari會象在大屏幕的
桌面瀏覽器那樣顯示你的頁面,寬度達到了980像素,然後縮小內容以適應iPhone的小屏幕,因此用戶在iPhone看這個頁面時感覺字體就比較小了,
也比較模糊,必須要放大才能看得真切,對於一個普通的Web頁面似乎可以接受,但對於一個常用的應用程序就沒幾個人能夠受得了。

幸運的是可以使用特殊的Meta元素可視區進行糾正:

<meta
name="viewport" content="width=device-width"/>

這個元素通知瀏覽器使用設備的寬度作為可視區的寬度,而不是默認的980像素了,我們可以看看兩個不同的例子。


例3(鏈接:
viewport.html)顯示了一個簡單的段落元素,沒有Meta元素可視區,字體有點模糊。在iPhone中運行的實際情況如下圖所示。

圖 1 無可視區的顯示效果


例4(鏈接:
/viewport.html)包括了一個可視區元素,現在設備寬度只有320像素,字體也比前一個例子更清晰了。在iPhone中運行的實際情況如下圖
所示。

圖 2 有可視區的顯示效果


另外,你還可以手動設置device-width的值,例如,假設你的博客頁面的寬度是750像素,那麼桌面屏幕最佳大小就是800x600像素,例
5(鏈接:
/fixed750.html)顯示了一個刪減版本,如果你在iPhone中瀏覽它,你會看到980像素剩下的空間都填充了白色。

為了消除額外的空間,可以使用meta元素可視區將寬度設為780像素:

<meta
name="viewport" content="width=780"/>

例6(鏈接:/fixed750-viewport.html)顯示了meta元素可視區布局被固定後的效果。

Meta元素可視區的內容可以包括多個逗號分隔的值,如initial-scale –
用戶最初看到頁面時的放大級別,對於Web應用程序,一個常見的設置是:

<meta
name="viewport" content="width=device-width,initial-scale=1,user-scalable=no"/>

這個元素設置寬度為設備的最大寬度,禁止用戶放大和縮小

F. JS如何獲取頁面可見區域高度

window.document.body.clientHeight就可以

window.screen.availWidth 返回當前屏幕寬度(空白空間)
window.screen.availHeight 返回當前屏幕高度(空白空間)
window.screen.width 返回當前屏幕寬度(解析度值)
window.screen.height 返回當前屏幕高度(解析度值)
window.document.body.offsetHeight; 返回當前網頁高度
window.document.body.offsetWidth; 返回當前網頁寬度

我們這里說說四種瀏覽器對 document.body 的 clientHeight、offsetHeight 和 scrollHeight 的解釋。
這四種瀏覽器分別為IE(Internet Explorer)、NS(Netscape)、Opera、FF(FireFox)。
clientHeight
大家對 clientHeight 都沒有什麼異議,都認為是內容可視區域的高度,也就是說頁面瀏覽器中可以看到內容的這個區域的高度,一般是最後一個工具條以下到狀態欄以上的這個區域,與頁面內容無關。
offsetHeight
IE、Opera 認為 offsetHeight = clientHeight + 滾動條 + 邊框。
NS、FF 認為 offsetHeight 是網頁內容實際高度,可以小於 clientHeight。
scrollHeight
IE、Opera 認為 scrollHeight 是網頁內容實際高度,可以小於 clientHeight。
NS、FF 認為 scrollHeight 是網頁內容高度,不過最小值是 clientHeight。
簡單地說
clientHeight 就是透過瀏覽器看內容的這個區域高度。
NS、FF 認為 offsetHeight 和 scrollHeight 都是網頁內容高度,只不過當網頁內容高度小於等於 clientHeight 時,scrollHeight 的值是 clientHeight,而 offsetHeight 可以小於 clientHeight。
IE、Opera 認為 offsetHeight 是可視區域 clientHeight 滾動條加邊框。scrollHeight 則是網頁內容實際高度。
同理
clientWidth、offsetWidth 和 scrollWidth 的解釋與上面相同,只是把高度換成寬度即可。
=======================================================================
clientHeight與offsetHeight的區別
許多文章已經介紹了clientHeight和offsetHeight的區別,就是clientHeight的值不包括scrollbar的高度,而offsetHeight的值包括了scrollbar的高度。然而,clientHeight和offsetHeight的值到底由什麼組成的呢?如何計算這兩個數的值?
1. clientHeight和offsetHeight的值由什麼決定?
假如我們有以下的DIV,主要顯示的文字為"This is the main body of DIV"。
如上圖所示,clientHeight的值由DIV內容的實際高度和CSS中的padding值決定,而offsetHeight的值由DIV內容的實際高度,CSS中的padding值,scrollbar的高度和DIV的border值決定;至於CSS中的margin值,則不會影響clientHeight和offsetHeight的值。
2. CSS中的Height值對clientHeight和offsetHeight有什麼影響?
首先,我們看一下CSS中Height定義的是什麼的高度。如在本文最後部分「APPENDIX示例代碼」(註:以下稱為「示例代碼」)中,innerDIVClass的Height值設定為50px,在IE下計算出來的值如下所示。也就是說,在IE裡面,CSS中的Height值定義了DIV包括padding在內的高度(即offsetHeight的值);在Firefox裡面,CSS中的Height值只定義的DIV實際內容的高度,padding並沒有包括在這個值裡面(70 = 50 + 10 * 2)。
in IE:
innerDiv.clientHeight: 46
innerDiv.offsetHeight: 50
outerDiv.clientHeight: 0
outerDiv.offsetHeight: 264
in Firfox:
innerDiv.clientHeight: 70
innerDiv.offsetHeight: 74
outerDiv.clientHeight: 348
outerDiv.offsetHeight: 362
在上面的示例中,也許你會很奇怪,為什麼在IE裡面outerDiv.clientHeight的值為0。那是因為示例代碼中,沒有定義outerDIVClass的Height值,這時,在IE裡面,則clientHeight的值是無法計算的。同樣,在示例代碼中,如果將innerDIVClass中的Height值去年,則innerDIV.clientHeight的值也為0。(註:在Firefox下不存在這種情況)。
如果CSS中Height值小於DIV要顯示內容的高度的時候呢(當CSS中沒有定義overflow的行為時)?在IE裡面,整個clientHeight(或者offsetHeight)的值並沒有影響,DIV會自動被撐大;而在Firefox裡面,DIV是不會被撐開的。如在示例代碼中,將innerDivClass的Height值設為0,則計算結果如下所示。IE裡面的DIV被撐開,其clientHeight值等於內容的高度與padding*2的和;而Firefox裡面,文字將溢出DIV的邊界,其clientHeight值正好是padding值的兩倍。
In IE:
innerDiv.clientHeight: 38
innerDiv.offsetHeight: 42
outerDiv.clientHeight: 0
outerDiv.offsetHeight: 256
In Firefox:
innerDiv.clientHeight: 20
innerDiv.offsetHeight: 24
outerDiv.clientHeight: 298
outerDiv.offsetHeight: 312

G. 前端優化-LCP

LCP是最大內容繪制的簡稱。LCP是用來測量感知載入速度。感知載入速度是以用戶為中心的重要指標。因為該項指標會在頁面的主要內容基本載入完成時,在頁面載入時間軸中標記出相應的點,迅捷的LCP有助於讓用戶確信頁面時有效的。以前的指標測量比如load(載入)或者DOMContentLoad(DOM內容載入完畢)並不是很好,因為這些指標並不一定與用戶看到的內容相對應。而向First Contentful Paint 首次內容的繪制(FCP)這類以用戶為中心的新指標只會捕獲載入最開始的部分。如果某個頁面顯示時一段啟動動畫或者載入之時,那麼這些時刻與用戶的關聯性並不大。First Meaningful Paint 首次有效繪制(FMP)和Speed Index速度指數(SI),這些指標能夠捕獲到更多初始後的載入速度,但是這些指標復雜,難以理解,而且容易出錯。
LCP指標會根據頁面首次開始載入的時間點來報告可視區域可見的最大圖像或者文本完成渲染的相對時間.良好的LCP的時間時2.5,較差的值為4.0s.最大內容的繪制考量的元素類型為

報告給最大內容繪制的元素大小通常時用戶在可視區域可見的大小,如果元素延伸到可視區域之外,或者任何元素被剪裁或者包含不可見的溢出,那麼這部分不計入元素的帶線啊哦。對於在原始尺寸之上經過調整的圖像元素,報告給指標的元素大小為可見尺寸或者原始尺寸。

網頁通常時分階段載入的,因此,頁面上最大元素也可能會發生變化。為了應對這種潛在的變化,瀏覽器會繪制第一幀立即發送一個largest-contentful-paint類型的PerformanceEntry,用於識別最大內容元素,但是,在渲染後續幀之後,瀏覽器會在最大內容元素發生變化時候分發另一個PerfornacneFanceEntry。需要主要的是,一個元素只能在渲染完成並且對用戶可見之後才視為最大元素,尚未載入點額元素不能視為渲染完成。在字體阻塞期使用網頁字體的文本節點也是這樣。在這種情況下,較小的元素可能會被報告稱最大元素,但一旦更大的元素完成渲染,就會通過另外一個PerformanceEntry對象進行報告

為了使計算和分發新性能條目的性能開銷保持在較低的水平,對元素大小或者位置的更改不會生成新的LCP候選對象,只有元素在可視區域的初始化大小和位置會納入考量范圍。也就是說,最初在屏幕外完成渲染,然後過濾到屏幕上的圖像可能不會得到報告,這也意味著最初可視區域內進行渲染,然後被推出到可視區域外的元素人講報告其在可視區域的初始化大小

LCP主要受四個因素影響