課外加餐:3 | 載入階段效能:使用 Audits 來優化 Web 效能
前言:該篇說明:請見 說明 —— 瀏覽器工作原理與實踐 目錄
作為一名前端工程師,除了需要編寫功能性的程式碼以外,還需要關注 Web 應用的效能問題,我們應該有能力讓 Web 應用佔用最小的資源,並以最高效能執行,這也是前端工程師進階的必要能力。既然效能這麼重要,那麼進來聊聊 Web 效能問題。
到底什麼是 Web 效能?
我們看下 wiki 對 Web 效能的 定義。(反正我是打不開)
Web 效能描述了 Web 應用在瀏覽器上的載入和顯示的速度。
因此,討論 Web 效能 其實就是討論 Web 應用速度。關於 Web 應用的速度,需要從兩個階段來考慮:
- 頁面載入階段
- 頁面互動階段
在本文中,會將焦點放到第一個階段:頁面載入階段的效能,在下篇文章中,則會重點分析頁面互動階段的效能。
效能檢測工具:Performance VS Audits
要想優化 Web 的效能,就需要有監控 Web 應用的效能資料,那如何監控呢?
如果沒有工具來模擬各種不同的場景並統計各種效能指標,那麼定位 Web 應用的效能瓶頸將是一件非常困難的任務。幸好,Chrome 為我們提供了非常完善的效能檢測工具:Performance 和 Audits ,它們能夠準確統計頁面在載入階段和執行階段的一些核心資料,諸如任務執行記錄、首屏展示花費的時長等,有了這些資料就能很容易定位到 Web 應用的 效能瓶頸
首先 Performance 非常強大,因為它提供了非常多的執行時資料,利用這些資料就可以分析出來 Web 應用的瓶頸。但是要完全學會其使用方式卻是非常有難度的,其難點在於這些資料涉及到了特別多的概念,而這些概念又和瀏覽器的系統架構、訊息迴圈機構、渲染流水線等知識緊密聯絡在了一起。
相反,Audtis 就簡單了很多,它將檢測到的細節資料隱藏在背後,只提供給我們一些直觀的效能資料,同時,還會給我們提供一些優化建議。
Performance 能讓我們看到更多細節資料,但是更加複雜,Audits 就比較智慧,但是隱藏了更多細節。為了能夠讓你循序漸進地理解內容,所以本節先從簡單的 Audits 入手,看看如何利用它來檢測和優化頁面在載入階段的效能,然後在下一節再來分析 Performance。
檢測之前準備工作
不過在檢測 Web 的效能指標之前,還要配置好工作環境,具體地講,你需要準備以下內容:
- 首先準備 Chrome Canary 版的瀏覽器,Chrome Canary 是採用最新技術構建的,它的開發者工具和瀏覽器特性都是最新的,所以我推薦你使用 Chrome Canary 來做效能分析。當然你也可以使用穩定版的 Chrome。
- 然後需要在 Chrome 的隱身模式下工作,這樣可以確保安裝的擴充套件、瀏覽器快取、Cookie 等資料不會影響到檢測結果。
利用 Audits 生成 web 效能報告
注:Audits 現在在瀏覽器中 是 Lighthouse 板塊
環境準備好之後就可以生成站點在載入階段的效能報告了,這裡拿 B 站 作為分析的例子。
- 首先開啟瀏覽器的隱身視窗(其實就是無痕模式),Windows 系統下面的快捷鍵是 Control + Shift + N,Mac 系統下的快捷鍵是 Command + shift + N
- 然後在隱身視窗中輸入 B 站的連結。
- 開啟 Chrome 的開發者工具,選擇 Audits 標籤(現在是 Lighthouse 標籤)
最終開啟的頁面如下:(後面會將 Audits 都改成 Lighthouse)
Audits 介面 / Lighthouse 介面
觀察上圖中的 Lighthouse 介面可以看到,在生成報告之前需要先配置 Lighthouse,配置模組主要由兩部分組成,一個是監測型別(Categories),另一個是裝置型別(Device)。
監控型別(Categories)是指需要監控哪些內容,這裡有五個對應的選項,它們的功能分別是:
- 監測並分析 Web 效能(Performance)
- 監測並分析 PWA(Progressive Web App)程式的效能
- 監測並分析 Web 應用是否採用了最佳實踐策略(Best practices)
- 監測並分析是否實施了無障礙功能(Accessibility),無障礙功能讓一些身體有障礙的人可以方便地瀏覽 你的 Web 應用
- 監測並分析 Web 應用是否實施了 搜尋引擎優化(SEO)
本文只需要關注 Web 應用的載入效能,所以勾選第一個 Performance 選項就可以了。
再看裝置部分(Device),它有兩個選項,Mobile 選項是用來模擬移動裝置環境的,另一個 Desktop 選項是用來模擬桌面環境的。這裡選擇移動裝置選項,因為目前大多數流量都是由移動裝置產生的,所以移動裝置上的 Web 效能顯得更加重要。
配置好選項後就可以點選 Generate report 按鈕 來生成報告了。
解讀效能報告
點選生成報告的按鈕後大概需要等待下,Lighthouse 就可以生成最終的分析報告了,如下:
生成的報告圖
觀察上圖的分析報告,中間圓圈的數字表示該站點在載入過程中的總體 Web 效能得分,總分是 100 分。目前的得分是 53 分,表示該站點載入階段的效能還有很大的提升空間。
Lighthouse 除了生成效能指標外,還會分析該站點並提供了很多優化建議,我們可以根據這些建議來改進 Web 應用以獲得更高的得分,進而獲得更好的使用者體驗效果。
既能分析 Web 效能得分又能給出優化建議,所以 Lighthouse 的分析報告還是非常有價值的,那麼接下來就來解讀下 Lighthouse 生成的效能報告。
報告的第一部分是效能指標(Metrics),如下圖所示:
效能指標
觀察上圖可以發現效能指標下一共有六項內容,這六項內容分別對應了從 Web 應用的載入到頁面展示完成的這段時間中,各個階段所消耗的時長。在中間還有一個 View Original Trace 按鈕,點選該按鈕可以跳轉到 Performance 標籤,並且檢視這些階段在 Performance 中所對應的位置。最下方是載入過程中各個時間段的螢幕截圖。
報告的第二部分是可優化項(Opportunities),如下圖:
可優化項(Opportunities)
這些可優化項是 Lighthouse 發現頁面中的一些可以直接優化的部分,你可以對照 Lighthouse 給的這些提示來優化 Web 應用。
報告的第三部分是 手動診斷(Diagnostics),如下圖:
手動診斷(Diagnostics)
在手動診斷部分,採集了一些可能存在效能問題的指標,這些指標可能會影響到頁面的載入效能,Lighthouse 把詳情列出來,並讓你依據實際情況來手動排查每一項。
報告的最後一部分是 執行時設定(Runtime Settings),如下圖:
註釋:該部分在目前的 Chrome 中沒看到了,現在的最後部分是:Passed Audits 。現在的部分就不列出來了,只列出老師說的圖 和 解說。
以前的 執行時設定(Runtime Settings)
觀察上圖,這是執行時的一些基本資料,如果選擇移動裝置模式,你可以看到傳送網路請求時的 User Agent 會變成裝置相關資訊,還有會模擬裝置的網速,這個體現在網路限速上。
根據效能報告優化 Web 效能
現在有了效能報告,接下來就可以依據效能報告來分析如何優化 Web 應用了。最直接的方式是想辦法提高效能指標的分數,而效能指標的分數是由六項指標決定的,它們分別是:
- 首次繪製(First Paint) FP
- 首次有效繪製(First Meaningfull Paint) —— 現在沒有這個了 FMP
- 首屏時間(Speed Index)
- 首次 CPU 空閒時間(First CPU Idle)—— 現在沒有這個了
- 完全可互動時間(Time to Interactive)
- 最大估計輸入延時(Max Potential First Input Delay)——現在沒有這個了
現在變成了:
- 首次繪製(First Paint)
- 首屏時間(Speed Index)
- 最大內容繪製(Largest Contentful Paint) LCP
- 完全可互動時間(Time to Interactive)
- 總阻塞時間(Total Blocking Time)
- 累積佈局偏移(Cumulative Layout Shift)
那麼接下來會逐一分析每個指標的含義,並討論如何提升指標的數值。這幾項都是在頁面載入過程中的效能指標,所以要弄明白每個指標的具體含義還得結合頁面的載入過程來分析。如下圖:從頁面的載入到展示的過程圖:
頁面載入過程
觀察上圖可以發現,在渲染程序確認要渲染當前的請求後,渲染程序會建立一個空白頁面,我們把建立空白頁面的這個時間點稱為 First Paint,簡稱 FP。
然後渲染程序繼續請求關鍵資源,在《25 | 頁面效能:如何系統地優化頁面?》一文中介紹過關鍵資源,並且知道了關鍵資源包括了 JS檔案和 CSS 檔案,因為關鍵資源會阻塞頁面的渲染,所以需要等待關鍵資源載入完成後才能進一步執行頁面的繪製。
上圖中,bundle.js 是關鍵資源,因此需要完成載入之後,渲染程序才能執行該指令碼,然後指令碼會修改 DOM,引發重繪和重排等一系列操作,當頁面中繪製了第一個畫素時,我們把這個時間點稱為 First Content paint ,簡稱 FCP。
接下來繼續執行 JS 指令碼,當首屏內容完全繪製完成時,我們把這個時間點稱為 Largest Content Paint,簡稱 LCP。
在 FCP 和 LCP 之間,還有一個 FMP,這個是首次有效繪製,由於 FMP 計算複雜而且容易出錯,現在不推薦使用該指標,所以這裡不做過多介紹了。
接下來 JS 指令碼執行結束,渲染程序判斷該頁面的 DOM 生成完畢,於是觸發了 DOMContentLoad 事件。等所有資源都載入結束後,再觸發 onload 事件。
好了,以上就是頁面在載入過程中各個重要的時間節點,瞭解了這些時間節點,我們就可以來聊聊效能報告的各個指標的含義並討論如何優化這些指標。
先來分析下 第一項指標 FP,如果 FP 時間過久,那麼直接說明了一個問題,那就是頁面的 HTML 檔案可能由於網路原因導致載入時間過久,這塊具體的分析過程可以參考《21 | Chrome 開發者工具:利用網路面板做效能分析》一文。
第二項是 FMP,上面也提到過由於 FMP 計算複雜,所以現在不建議使用該指標了,另外由於 LCP 的計算規則簡單,所以推薦使用 LCP 指標,具體文章可以參考這裡(連結打不開)。不過不管是 FMP 還是 LCP,優化它們的方式都是類似的,你可以結合上圖,如果 FMP 和 LCP 消耗時間過久,那麼有可能是載入關鍵資源花的時間過久,也有可能是 JS 執行過程中所花的時間過久,所以我們可以針對具體的情況來具體分析。
第三項是首屏時間(Speed Index),這就是上面提到的 LCP,它表示填滿首屏頁面所消耗的時間,首屏時間的值越大,那麼載入速度越慢,具體的優化方式同優化第二項 FMP 一樣。
第四項是首次 CPU 空閒時間(First CPU Idle),也稱為 First interactive,它表示頁面達到最小化可互動的時間,也就是說並不需要等到頁面上的所有元素都可互動,只要可以對大部分使用者輸入做出響應即可。要縮短首次 CPU 空閒時長,就需要儘可能快的載入完關鍵資源,儘可能快地渲染出首屏內容,因此優化方式和第二項 FMP 和第三項 LCP 是一樣的。
第五項是完全可互動時間(Time to Interactive),簡稱 TTI,它表示頁面中所有元素都達到了可互動的時長。簡單理解就這時候頁面的內容已經完全顯示出來了,所有的 JS 事件已經註冊完成,頁面能夠對使用者的互動做出快速響應,通常滿足響應速度在 50 毫秒以內。如果要解決 TTL 時間過久的問題,我們可以推遲執行一些和生成頁面無關的 JS 工作。
第六項是最大估計輸入延時(Max Potential First Input Delay),這個指標是估計你的web 頁面在載入最繁忙的階段,視窗中響應使用者輸入所需的時間,為了改善該指標,可以使用 WebWorker 來執行一些計算,從而釋放主執行緒。另一個有用的措施是重構 CSS 選擇器,以確保它們執行較少的計算。
總結
本文的主要內容: