1. 程式人生 > >在瀑布下用火焰烤餅:三步法助你快速定位網站效能問題(超詳細)

在瀑布下用火焰烤餅:三步法助你快速定位網站效能問題(超詳細)

> DevUI是一支兼具設計視角和工程視角的團隊,服務於華為雲[DevCloud](https://www.huaweicloud.com/devcloud/)平臺和華為內部數箇中後臺系統,服務於設計師和前端工程師。
> 官方網站:[devui.design](https://devui.design/)
> Ng元件庫:[ng-devui](https://github.com/DevCloudFE/ng-devui)(歡迎Star)
> 官方交流:新增DevUI小助手(devui-official)
> DevUIHelper外掛:DevUIHelper-LSP(歡迎Star) # 引言 效能,是一個問題。 每個專案成長到一定的規模,都幾乎必然要遇到效能問題,當遇到效能問題時,我們是: > 一臉懵逼,就知道很卡、很慢,不知道為什麼 還是 > 能夠快速洞察效能瓶頸,找到行之有效的優化方案 取決於我們對效能的理解深淺,以及是否有一套好的工具和方法。 接下來給大家分享我自己在定位業務效能問題時常用的三步法,為了方便記憶,我把它總結為一句話: > 在瀑布下用火焰烤餅 話不多說,喝口水直接開擼! ![](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/85b70bab2d344a27b525f24f47b84b11~tplv-k3u1fbpfcp-watermark.image) # Performance面板簡介 介紹三步法之前,先來簡單瞭解下Chrome開發者工具的Performance效能面板,以及效能分析報告的基本組成。 ## 生成效能分析報告 以DevUI團隊的掘金個人主頁為例,使用Chrome瀏覽器訪問:[https://juejin.cn/user/712139267650141](https://juejin.cn/user/712139267650141) 然後按F12開啟Chrome的開發者工具,選擇Performance效能面板。 這時我們會看到一個簡單的指引: ![](https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/df4ae1be8e02485798f49350f7e57399~tplv-k3u1fbpfcp-watermark.image) 指引裡面有兩個按鈕,上面的按鈕是手動錄製,下面的是自動錄製,我們點選傻瓜式的自動錄製,自動錄製會自動重新整理頁面,在頁面載入完成之後,生成該頁面的效能分析報告,無需人工干預,非常方便。 等個幾秒鐘報告就生成好了,一眼看去,花花綠綠的,不知道從何看起? ![](https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/df59c1504dff4751a0e6e7898022f4c4~tplv-k3u1fbpfcp-watermark.image) ## 效能報告的組成 我們對生成的效能分析報告做一個簡單的面板分類,看起來就很清晰了。 ![](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/26b68ba524b14e949355a3f57ba7aecb~tplv-k3u1fbpfcp-watermark.image) ### 工具欄 效能報告的頂部是一個工具欄(或者叫控制面板),裡面有一堆按鈕,我這邊用得比較多的是前面三個,其中前兩個在指引裡已經介紹過了,第三個是用來清除報告的。 還有兩個隱藏的功能也很有用,一個是模擬慢網速的,另一個是模擬慢CPU的,對移動端應用做效能優化可能會用到。 ![](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/f847a37efac64d15a6e379f76df43b2b~tplv-k3u1fbpfcp-watermark.image) ### 概覽面板 工具欄下面是一個概覽面板,顯示了整個頁面載入過程中的FPS(Frames Per Second,每秒傳輸幀數),用來評估頁面的流暢度,有大片紅色說明頁面可能存在卡頓。 FPS下面是CPU處理各個任務花費的時間,再往下是網路請求的耗時,概覽面板最下面是每一幀的截圖。 ### 執行緒面板 概覽面板往下是執行緒面板,預設展開的是網路請求瀑布圖,其他執行緒的詳情都是收起的。 每個執行緒面板對效能分析都有價值,而我最常用的是瀑布圖和火焰圖,後面會重點分析這兩個圖,如何利用這兩張圖來分析網站的效能瓶頸。 ### 記憶體面板 再往下是記憶體面板,記憶體面板需要在控制面板中手動開啟,它是一個分類的記憶體佔用折線圖。 每條折線是一種任務隨時間推移的記憶體佔用: - JS堆疊 - 文件 - HTML節點 - 事件監聽 - GPU記憶體 ### 詳情面板 最下面是詳情面板,首先看到的是一個餅圖,這個餅圖顯示了各種型別任務的佔比,這個非常有用,能否一眼看出什麼型別的任務是效能瓶頸。 是資源載入還是指令碼執行?是頁面渲染還是影象繪製?又或者是空閒時間太長? # 第一步:看餅圖 剛才介紹Performance面板的組成時,提到了3個非常有用的效能分析利器,分別是`詳情餅圖`、`請求瀑布圖`和`主執行緒火焰圖`。 我把這三張圖總結成一句話: > 在瀑布下用火焰烤餅 這句話也是我自己在做效能分析和優化時,屢試不爽的小技巧。 詳情面板中的餅圖用於展示各種型別任務的耗時佔比。 主要有以下幾種任務: - 藍色是資源載入 - 黃色是指令碼執行 - 紫色是頁面渲染 - 綠色是圖形繪製 - 白色是空閒時間 還是舉剛才的例子。 ![](https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/9b6969cf9d9f4540bfd55ef8460e1acb~tplv-k3u1fbpfcp-watermark.image) 從餅圖可以看出佔比最多的是`指令碼執行`和`空閒`。 指令碼執行時間長,我們大概可以猜測裡面可能存在長任務(Long task); 而空閒佔比多可能是等待伺服器的響應時間太長。 餅圖可以快速形成基本的判斷,而具體原因則需要分析瀑布圖和火焰圖。 # 第二步:看瀑布圖 我們來看下請求瀑布圖,瀑布圖和火焰圖都是執行緒面板的一部分,瀑布圖的橫軸是時間軸,瀑布圖上有很多五顏六色的色塊,這些色塊就是`請求塊`,每種顏色代表一類資源: - 藍色是HTML檔案 - 紫色是CSS檔案 - 黃色是JavaScript檔案 - 綠色是圖片 - 灰色是後臺介面 我們主要關注那些`長色塊`,長色塊意味著耗時長,可能是效能瓶頸。 還是看下掘金個人主頁的瀑布圖。 ![](https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/8a36050601ea4e57adfe2910f26cb457~tplv-k3u1fbpfcp-watermark.image) ## 總結瀑布圖的特點 我們先觀察這張圖有什麼特點,圖形觀察能力,相信大家小學就已經培養起來了,大致我們可以總結出以下比較明顯的特點: - 特點一:大瀑布被分成三個小瀑布 - 特點二:最左邊的小瀑布大部分都是黃色色塊,中間的小瀑布大部分是灰色色塊,最右邊的小瀑布大部分是綠色色塊 - 特點三:前兩個瀑布之間有一段間距,中間什麼色塊都沒有 - 特點四:後兩個瀑布被一個灰色色塊的“尾巴”連在了一起 - 特點五:頂部有一個超長的灰色色塊 類似的特點我們還可以總結出很多來,但是這些特點說明了什麼呢?能否幫助我們定位效能瓶頸呢? 回答這些問題需要我們對瀑布圖以及瀏覽器原理有很多的認識,我們一步步來分析吧。 ## 分析瀑布圖的含義 我們按從左到右,從上到下的順序進行分析,最左邊有兩個色塊,一個灰色色塊,一個藍色色塊,我們分別點選這兩個色塊,在詳情面板看下它們的詳情資訊。 先看灰色色塊 ![](https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/290be79443c0404ebf4b813c1ef5401d~tplv-k3u1fbpfcp-watermark.image) 我們有注意到這個請求的啟動器(Initiator)是一個Chrome外掛:[chrome://new-tab-page/omnibox.mojom-lite.js](chrome://new-tab-page/omnibox.mojom-lite.js) 因此我們不關注,接著看藍色色塊 ![](https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/ad291ed132794851965f3e0b54b89ef5~tplv-k3u1fbpfcp-watermark.image) 前面我們已經介紹了,藍色色塊代表HTML檔案,我們從詳情的`Mime Type`為`text/html`也可以驗證這一點。 我們滾動滑鼠滾輪,把這個瀑布圖放大,看這個藍色請求塊的細節 ![](https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/15437f73032e451bb120ab81c8ffa33e~tplv-k3u1fbpfcp-watermark.image) ### 請求塊的組成 通過檢視細節圖,我們有了新的發現: > 每個請求塊都由四部分組成: > 1. 左側線:代表請求傳送之前的時間(Before Request Sent) > 2. 淺色塊:代表請求已經發送(Request Sent),直到伺服器返回第一個位元組給瀏覽器(TTFB, Time to First Byte) > 3. 深色塊:伺服器返回的內容全部下載到瀏覽器(Content Download) > 4. 右側線:等待主執行緒處理(Waiting for main thread) 這個HTML檔案是整個網頁渲染的起點,成功請求並下載這個檔案,才會有接下來的故事。 這個請求塊的淺色塊部分佔比比較大,根據前面的介紹,淺色部分代表的是伺服器的響應速度,瀏覽器已經早早地發出了請求,伺服器卻遲遲才給迴應(第一個位元組到達瀏覽器)。 中間可能是網路慢,也可能是伺服器處理速度慢,需要具體排查,畢竟這個HTML檔案不算大,才111KBb,卻花了179ms。 對比另外一個檔案layouts.default.js,體積比它大124KB,請求耗時卻比它小一半多,才74ms。(後來發現這個資料不穩定,這個HTML檔案應該不至於構成效能瓶頸) 另外所有後續的請求都依賴於這個HTML,沒有它其他請求都不會發生,它是一個阻塞請求,效能必須要有保障。 ### 發現可能的效能瓶頸 我們繼續看右邊的請求塊,頂部那個超長的灰色塊依然是Chrome外掛的請求,我們不管,看下面那一堆黃色的請求塊,這些都是JavaScript檔案。 HTML檔案下載完了之後,就會開始一行一行解析其中的HTML標籤,遇到設定了誰、`src`