我們的目標是優先顯示與用戶要在網頁上執行的主要操作有關的內容。
上面這句話出自《關鍵呈現路徑》。
什麼是前端性能?
前端性能,即頁面性能,簡單來說就是能看到頁面內容的時間以及可以開始在頁面上操作的時間。
前端性能與瀏覽器的運作方式密切相關,故想要優化性能就要從瞭解瀏覽器是如何顯示頁面的入手。
瀏覽器顯示頁面的原理
基本流程:
- 獲取 HTML 文檔及樣式表文件
- 解析成對應的樹形數據結構
- DOM tree
- CSSOM tree
- 計算可見節點形成 render tree
- 計算 DOM 的形狀及位置進行佈局
- 將每個節點轉化爲實際像素繪製到視口上(柵格化)
render tree(頁面上所顯示的最終結果)是由 DOM tree(開發工具中所顯示的 HTML 所定義的內容結構)與 CSSOM tree(樣式表所定義的規則結構)合併並剔除不可見的節點所形成的,其中不包含如下節點:
- 本身不可見的
<html>
<head>
<meta>
<link>
<style>
<script>
- 設置了
display: none;
樣式的
資源加載:
- 執行 JavaScript 會阻止 DOM tree 構建
- 加載 CSS 會阻止 render tree 構建
- 無論是否爲阻止呈現的 CSS,都會被瀏覽器下載
默認情況下,JavaScript 腳本會在引入它的位置執行(如果是外聯腳本則還需要等待加載完畢),這時會阻斷 DOM tree 的構建;如果在運行腳本時瀏覽器尚未完成 CSS 的下載和 CSSOM tree 的構建,瀏覽器會將腳本執行延遲到這些操作結束之後。
影響性能的因素:
- 白屏
- HTML 和 CSS 的加載及解析速度
<head>
內的腳本加載及執行
- 首屏
- 圖片加載
<body>
內的腳本加載及執行
- render tree 的構建
- HTML 的複雜度
- CSS 的複雜度
- render tree 的繪製(柵格化)
- 顏色的複雜度
- 形狀的複雜度
怎麼提高前端性能?
提高以下幾個方面,總體性能就會得到大幅度提升:
- 縮短白屏時間;
- 加快首屏顯示;
- 儘快監聽主要操作的事件。
所要達到的理想指標:
- 60 f/s
優化關鍵呈現路徑
爲了在首次渲染時儘可能快,我們需要優化以下三個變量:
- 最小化關鍵資源數
- 最小化關鍵字節數
- 最小化關鍵路徑長度
常規步驟:
- 分析並描述關鍵路徑:資源數、字節數和長度;
- 減少關鍵資源的數量:刪掉、延遲下載或標記爲異步等等;
- 優化剩餘關鍵資源的加載順序:儘早下載所有關鍵資源以縮短關鍵路徑長度;
- 優化關鍵字節數以減少下載時間(往返次數)。
蒐集性能數據
通過 Navigation Timing API 可以獲取瀏覽器在處理網頁的關鍵步驟的時間戳。
其中,各步驟的意義如下:
- domLoading 表示開始解析第一批收到的 HTML 文檔的字節
- domInteractive 表示完成全部 HTML 的解析並且 DOM 構建完畢
- domContentLoaded 表示 DOM
與 CSSOM 皆已準備就緒
- 如果沒有解析器阻塞 JavaScript,DOMContentLoaded 事件會在 domInteractive 之後立即觸發
- 很多 JavaScript 框架會在執行它們自己的邏輯前等待這個事件的觸發
- domComplete 表示所有的處理都已完成並且所有的附屬資源都已經下載完畢
- loadEvent 作爲網頁加載的最後一步以便觸發附加的應用邏輯
PageSpeed 規則和建議
- 排除阻止呈現的 JavaScript 和 CSS
- 優化 JavaScript 的用法
- 推薦使用異步 JavaScript 資源
- Avoid synchronous server calls
- 延遲解析 JavaScript
- 避免運行時間長的 JavaScript
- 優化 CSS 的用法
- 將 CSS 放到文檔頭部
- 避免使用 CSS import
- 內聯阻止呈現的 CSS