Web性能優化
1 Web性能優化
Web網站的性能細線在幾個方面:
-
網站首頁加載速度
-
動畫的流暢度
通過分析瀏覽器的渲染原理、資源對渲染的影響,得出優化網站性能的辦法。
2 查看性能的工具
Chrome的 Timeline 面板錄制網頁加載的過程,分析記錄瀏覽器渲染過程中每個過程的耗時。
2.1 錄制時注意事項
-
禁用瀏覽器緩存: Network Tab 下的 disable cache
-
關閉Chrome擴展或者啟用隱身模式
-
根據使用場景,模擬真實的網絡加載情況: Network Tab 下的 throttling 下拉按鈕
2.2 Timeline 工具的各個組成
-
在 Main Thread 中可以看到頁面渲染的整個過程及耗時
3 瀏覽器渲染原理
3.1 DOM樹構建
DOM樹的構建過程
-
根據HTML文檔的內容,根據標簽進行分詞 Token
-
根據 Token 生產對應的節點 Node
-
將節點根據嵌套關系組合為一棵對象節點樹 DOM
瀏覽器解析文檔對象模型 DOM 是 增量進行 的,無需等待整個HTML文檔加載完畢,便可以開始解析 DOM
CSSOM 解析會阻塞 HTML Parser ;JavaScript腳本文件 執行 會阻塞HTML解析; CSS、JavaScript、Images和Font等靜態資源的異步加載的,渲染頁面與CSS解析與JavaScript執行會有相互的依賴
3.2 CSSOM樹的構建
CSSOM 的解析依賴于 選擇器 ,選擇器的匹配是從內到外的。所以選擇器嵌套層次越深,匹配的時間會越長。
CSSOM 只解析可視部分 body 標簽中的內容,將所有匹配的元素共同構建一個 CSSOM 樹, 從根節點一次向下,所有節點的屬性向下繼承
3.3 RenderTree樹的構建
利用DOM和CSSOM組合構建生成RenderTree,對應 Recaculate Style
RenderTree中包含所有渲染網頁必須的節點
無需渲染的節點不會被添加到RenderTree中,如 head 和 display:none; 的節點
visibility: hidden; 的節點會添加到RenderTree中
3.4 Layout
Layout 利用渲染樹的信息,計算渲染樹中所有節點在頁面上的 位置和大小 。
類似繪畫中各個元素位置擺放及尺寸規劃
會引起頁面重新Layout的操作: 所有改變節點位置和大小的操作
-
屏幕旋轉
-
瀏覽器視窗改變
-
與大小、位置相關的CSS屬性
-
增加與刪除DOM元素
Layout操作比較耗時,對于動畫中頻繁引起Layout的操作(元素位置移動), 最好使用transform代替,可以使用GPU進行動畫處理(將Layout重繪在GPU完成)
viewport
如果頁面 body 元素設置的寬度為 100% ,并且根元素 html 沒有明確設置寬度絕對值, 此時 body 元素的寬度等于 viewport 的寬度 vw
-
使用 meta 標簽可以設置瀏覽器 viewport 的尺寸。 <meta name="viewport" content="width=device-width">
-
device-width 為瀏覽器的理想視口(屏幕的物理分辨率)
-
在移動端,如果不設置 device-width ,默認 viewport 寬度為980px, 導致文字很小,需要放大
viewport 相當于可視內容布局的容器
3.5 Paint
填充Layout中的具體內容和樣式,將Layout生成的區域填充為最終顯示在屏幕上的像素
3.6 總結
-
瀏覽器通過 GET 請求獲取網頁HTML,同時將增量解析HTML文檔,生成 DOM 樹
-
解析 DOM 節點樹時,對于需要加載的資源 全部執行異步加載,但是 CSS 的解析、 JavaScript 的執行與 font 文件的下載會阻塞HTML Parser
-
局部 DOM 樹與 CSSOM 樹構建完成后, 立即組裝 RenderTree 進行渲染
4 資源對渲染的影響
頁面中加載的資源主要包括: css 、 js 腳本文件和 font 字體與 images 靜態資源,不同資源類型對渲染的影響不同。
4.1 瀏覽器渲染頁面的時機
增量解析解析 DOM 樹,并且完成相應 CSSOM 解析后(RenderTree依賴于 DOM 樹, CSSOM 樹),開始直接渲染頁面。
4.2 CSS加載會阻塞初次渲染
4.3 非關鍵資源
對于首頁無關的樣式,需要使用適當的方式避免其阻塞初次渲染:
-
document.write() 會阻塞頁面初次渲染
-
使用 media=print 媒體查詢,雖然加載樣式表,但只針對打印時才應用該樣式,不會阻塞初次渲染。
-
通過 DOM API引入CSS,可以避免阻塞。
-
CSS中 <link rel="preload" href="index_print.css" as="style" onload="this.rel='stylesheet'"> 。
4.4 JS文件
-
輸出:先輸出 Hello ,10s之后再輸出 World 。JS腳本 執行 會阻塞 HTML Parser ,但是 HTML Parser 是增量解析的, 并且CSS樣式的解析會阻塞JS腳本執行 ,當解析完 Hello 時,生成對應 DOM 節點,并且完成其 CSSOM ,直接開始渲染 Hello 節點。
-
腳本執行完成后再解析后續的 World
JS腳本執行會阻塞HTML Parser;
CSS解析會阻塞JS腳本執行:js可能會讀、寫CSSOM
雖然JS會阻塞HTML Parser解析; 但是瀏覽器的資源異步加載機制 Preload 會異步加載 head 標簽內的資源
4.5 非關鍵JS資源解析阻塞的優化方案
-
將JS資源文件放在文檔底部,延遲JS的執行(但是存在必須解析完HTML才能加載JS資源,相較于 head 標簽中加載會慢)
-
使用 defer 延遲腳本執行: scipt 標簽的 defer 屬性,腳本會在HTML文檔解析完畢后再開始執行; 被 defer 的腳本在執行時嚴格按照HTML文檔中出現的順序執行 ---優勢可以提早加載JS資源,但是解析完HTML再執行
-
使用 async 異步執行腳本:
-
當 script 標簽有 async 屬性時,腳本執行不會阻塞HTML Parser,只要腳本加載完畢便開始執行
-
被 async 的腳本,不會嚴格按照在HTML文檔中的順序執行
-
async 適用于無依賴的外部獨立資源(注意不要錯誤操作狀態)
4.6 font 字體文件
-
font 字體文件會阻塞內容渲染
4.7 圖片資源
圖片資源的加載不會阻塞渲染,但是最好在HTML標簽中設置圖片的高度和寬度,可以在 Layout 時留出圖片渲染的空間,避免頁面的抖動
5 優化關鍵渲染路徑
優化目標是將下列三個指標壓縮到最低:
-
關鍵資源數---初次渲染時依賴的資源
-
關鍵資源的體積最小---壓縮文件或圖片
-
關鍵資源網絡來回數---網絡傳輸資源消耗很多時間
6 其余優化過程
-
HTTP2可以在傳輸HTML頁面后向客戶端推送頁面內包含的資源
-
減少資源的大小:壓縮
-
減少請求的來回時間
來自:https://segmentfault.com/a/1190000008693178
-