補齊Web前端性能分析的工具盲點

補齊Web前端性能分析的工具盲點

最近依然在研究大型專案,而大型專案最容易遇到的問題便是性能問題。 一般來說,當我們遇到性能瓶頸的時候,才會開始去進行相應的分析。 分析的方向除了業務本身的特點相關之外,常見的我們還可以藉助一些工具來發現問題。 本文一起來研究下,前端性能分析可以怎麼走~

# 前端性能分析工具(Chrome DevTools)

一般來說,前端的性能分析通常可以從時間空間兩個角度來進行:

  • 時間:常見耗時,如頁面載入耗時、渲染耗時、網路耗時、腳本執行耗時等
  • 空間:資源佔用,包括CPU佔用、記憶體佔用、本地緩存佔用等

那麼,下面來看看有哪些常見的工具可以借來用用。 由於我們的網頁基本上跑在瀏覽器中,所以基本上大多數的工具都來源於瀏覽器自身提供,首當其衝的當然是 Chrome DevTools。 本文我們也主要圍繞 Chrome DevTools 來進行說明。

## Lighthouse

Lighthouse 的前身是 Chrome DevTools 面板中的 Audits。 在 Chrome 60 之前的版本中, 這個面板只包含網路使用率和頁面性能兩個測量類別,從 Chrome 60 版本開始, Audits 面板已經被 Lighthouse 的整合版取代。 而在最新版本的 Chrome 中,則需要單獨安裝 Lighthouse 拓展程式來使用,也可以通過腳本來使用。

### 架構

下面是 Lighthouse 的組成部分:

  • 驅動(Driver):和 Chrome Debugging Protocol 進行互動的介面
  • 收集器(Gatherers):使用驅動程式收集頁面的訊息,收集器的輸出結果被稱為 Artifact
  • 審查器(Audits):將 Artifact 作為輸入,審查器會對其運行測試,然後分配通過/失敗/得分的結果
  • 報告(Report):將審查的結果分組到面向用戶的報告中(如最佳實踐),對該部分應用加權和總體然後得出評分

### 主要功能

Lighthouse 會在一系列的測試下運行網頁,比如不同尺寸的設備和不同的網路速度。 它還會檢查頁面對輔助功能指南的一致性,例如顏色對比度和ARIA最佳實踐。

在比較短的時間內,Lighthouse 可以給出這樣一份報告(可將報告生成為 JSON 或 HTML):

這份報告從 5 個方面來分析頁面: 效能輔助功能最佳實務搜尋引擎最佳化PWA。 像性能方面,會給出一些常見的耗時統計。 除此以外,還會給到一些詳細的優化方向。

如果你希望短時間內對你的網站進行較全面的評估,可以使用 Lighthouse 來跑一下分數,確定大致的優化方向。

## Performance 面板

Performance 面板同樣有個前身,叫 Timeline。 該面板用於記錄和分析運行時性能,運行時性能是頁面運行時(而不是載入)的性能。

### 使用步驟

Performance 面板功能特別多,具體的分析也可以單獨講一篇了。 這裡我們簡單說一下使用的步驟:

  1. 在隱身模式下打開 Chrome。 隱身模式可確保 Chrome 以乾淨狀態運行,例如瀏覽器的擴展可能會在性能評估中產生影響。
  2. 在 DevTools 中,按兩下「Performance」選項卡,並進行一些基礎配置(更多參考官方說明)。
  3. 按照提示按下記錄,開始記錄。 進行完相應的操作之後,點擊停止。
  4. 當頁面運行時,DevTools 捕獲性能指標。 停止記錄后,DevTools 處理數據,然後在 Performance 面板上顯示結果。

### 主要功能

關於 Performance 怎麼使用的文章特別多,大家網上隨便搜一下就能搜到。 一般來說,主要使用以下功能:

  • 查看 FPS 圖表:當在 FPS 上方看到紅色條形時,表示幀速率下降得太低,以至於可能損害用戶體驗。 通常,綠色條越高,FPS 越高
  • 查看 CPU 圖表:CPU 圖表在 FPS 圖表下方。 CPU 圖表的顏色對應於性能板的底部的 Summary 選項卡
  • 查看 火焰圖:火焰圖直觀地表示出了內部的CPU分析,橫軸是時間,縱軸是調用指標,調用棧最頂端的函數在最下方。 啟用 JS 分析器後,火焰圖會顯示數據的每個 JavaScript 函數,可用於分析具體函數
  • 查看 Buttom-up:此檢視可以看到某些函數對性能影響最大,並能夠檢查這些函數的調用路徑

具體要怎麼定位某些性能瓶頸,可以參考官方文檔系列文章,這裡就不詳細介紹啦。

## Performance Monitor

打開 Chrome 控制台後,按組合鍵 ctrl + p (Mac 快速鍵為 command + p ),輸入 > Show Performance Monitor ,就可以打開 Performance Monitor 性能監視器。 主要的監控指標包括:

  • CPU usage:CPU 佔用率
  • JS head size:JS 記憶體使用大小
  • DOM Nodes:記憶體中掛載的 DOM 節點個數
  • JS event listeners:事件監聽數
  • ... :其他等等

大多數情況下,我們在進行性能優化的時候,使用上面一些工具也足以確定大致的優化方向。 更多的細節和案例,就不在這裡詳述了。

# 前端性能監控

除了具體的性能分析和定位,我們也經常需要對業務進行性能監控。 前端性能監控包括兩種方式:合成監控(Synthetic Monitoring,SYN)、真實用戶監控(Real User Monitoring,RUM)。

## 合成監控

合成監控就是在一個模擬場景里,去提交一個需要做性能審計的頁面,通過一系列的工具、規則去運行你的頁面,提取一些性能指標,得出一個審計報告。 例如上面介紹的 Lighthouse 就是合成監控。

合成監控的使用場景不多,一般可能出現在開發和測試的過程中,例如結合流水線跑性能報告、定位性能問題時本地跑的一些簡單任務分析等。 該方式的優點顯而易見:

  • 可採集更豐富的數據指標,例如結合 Chrome Debugging Protocol 獲取到的數據
  • 較成熟的解決方案和工具,實現成本低
  • 不影響真實使用者的性能體驗

## 真實用戶監控

真實用戶監控,就是使用者在我們的頁面上訪問,訪問之後就會產生各種各樣的性能指標。 我們在使用者訪問結束的時候,把這些性能指標上傳到我們的日誌伺服器上,進行數據的提取清洗加工,最後在我們的監控平臺上進行展示的一個過程。

我們提及前端監控的時候,大多數都包括了真實用戶監控。 常見的一些性能監控包括載入耗時、DOM 渲染耗時、介面耗時統計等,而對於頁面載入過程,可以看到它被定義成了很多個階段:

而我們要做的,則是在力所能及的地方進行打點、計算、採集、上報,該過程常常需要藉助 Performance Timeline API。 將需要的數據發送到服務端,然後再對這些數據進行處理,最終通過可視化等方式進行監控。 因此,真實用戶監控往往需要結合業務本身的前後端架構設計來建設,其優點也比較容易理解:

  • 完全還原真實場景,減去類比成本
  • 數據樣本足夠抹平個體的差異
  • 採集數據可用於更多場景的分析和優化

對比合成監控,真實用戶監控在有些場景下無法拿到更多的性能分析數據(例如具體哪裡 CPU 佔用、記憶體佔用高),因此更多情況下作為優化效果來參考。 這些情況下,具體的分析和定位可能還是得依賴合成監控。

但真實用戶監控也有自身的優勢,例如 TCP、DNS 連接耗時過高,在各種環境下的一些運行耗時問題,合成監控是很難發現的。

# 性能分析自動化

我們在開發過程中,也常常需要進行性能分析。 而前端的性能分析上手成本也不低,除了基本的頁面載入耗時、網路耗時,更具體的定位往往需要結合前面介紹的 Performance 面板、FPS、CPU、火焰圖等一點點來分析。

如果這一塊想要往自動化方向發展,我們可以怎麼做呢?

## 使用 Lighthouse

前面也有介紹 Lighthouse,它提供了腳本的方式使用。 因此,我們可以通過自動化任務跑腳本的方式,使用 Lighthouse 跑分析報告,通過對比以往的數據來進行功能變更、性能優化等場景的性能回歸。

使用 Lighthouse 的優勢在於開發成本低,只需要按照官方提供的配置來調整、獲取自己需要的一些數據,就可以快速接入較全面的 Lighthouse 擁有的性能分析能力。

不過由於 Lighthouse 同樣基於 HubSpot(Chrome DevTools Protocol),因此除了實現成本降低了,HubSpot 缺失的一些能力它也一樣會缺失。

## Chrome DevTools Protocol

Chrome DevTools Protocol 允許第三方對基於 Chrome 的 Web 應用程式進行檢測、檢查、調試、分析等。 有了這個協議,我們就可以自己開發工具獲取 Chrome 的數據了。

### 認識 Chrome DevTools 協定

Chrome DevTools 協定基於 WebSocket,利用 WebSocket 建立連接 DevTools 和瀏覽器內核的快速數據通道。

我們使用的 Chrome DevTools 其實也是一個 Web 應用。 我們使用DevTools的時候,瀏覽器內核Chromium本身會作為一個服務端,我們看到的瀏覽器調試工具介面,通過Websocket和Chromium進行通信。 建立過程如下:

  1. DevTools 將作為 Web 應用程式,Chromium 作為服務端提供連接。
  2. 通過 HTTP 提取 HTML、JavaScript 和 CSS 檔。
  3. 資源載入後,DevTools 會建立與瀏覽器的 Websocket 連接,並開始交換 JSON 消息。

同樣的,當我們通過 DevTools 從 Windows、Mac 或 Linux 計算機遠端調試 Android 設備上的即時內容時,使用的也是該協定。 當 Chromium 以一個 --remote-debugging-port=0 標誌啟動時,它將啟動 Chrome DevTools 協定伺服器。

### Chrome DevTools 協定域劃分

Chrome DevTools協定具有與瀏覽器的許多不同部分(例如頁面、Service Worker 和擴充程式)進行互動的 API。 該協定把不同的操作劃分為了不同的域(domain),每個域負責不同的功能模組。 比如 DOM 、 、 、 和 Debugger Network Console Performance 等,可以理解為 DevTools 中的不同功能模組。

使用該協定我們可以:

  • 獲取 JS 的 Runtime 數據,常用的如 window.performancewindow.chrome.loadTimes()
  • 獲取 NetworkPerformance 數據,進行自動性能分析
  • 使用 PuppeteerHubSpotSession,與瀏覽器的協定通信會變得更加簡單

### 與性能相關的域

本文講性能分析相關,因此這裡我們只關注和性能相關的域。

1. Performance。 Performance 域中 Performance.getMetrics() 可以拿到取得執行時效能指標包括:

  • Timestamp: 採取度量樣本的時間戳
  • Documents: 頁面中的文件數
  • Frames: 頁面中的幀數
  • JSEventListeners: 頁面中的事件數
  • Nodes: 頁面中的 DOM 節點數
  • LayoutCount: 全部或部分頁面佈局的總數
  • RecalcStyleCount: 頁面樣式重新計算的總數
  • LayoutDuration: 所有頁面佈局的合併持續時間
  • RecalcStyleDuration: 所有頁面樣式重新計算的總持續時間
  • ScriptDuration: JavaScript 執行的持續時間
  • TaskDuration: 瀏覽器執行的所有任務的合併持續時間
  • JSHeapUsedSize: 使用的 JavaScript 棧大小
  • JSHeapTotalSize: JavaScript 棧總大小

2. Tracing。 Tracing 域可獲取頁面載入的DevTools性能跟蹤。 可以使用 Tracing.startTracing.stop 創建可在 Chrome DevTools 或時間軸查看器中打開的跟蹤檔。

我們能看到生成的 JSON 檔長這樣:

這樣的 JSON 文件,我們可以丟到 DevTools Timeline Viewer 中,可以看到對應的時間軸和火焰圖:

3. Runtime。 Runtime 域通過遠程評估和鏡像物件暴露 JavaScript 的運行時。 可以通過 Runtime.getHeapUsage 獲取 JavaScript 棧的使用方式,通過 Runtime.evaluate 計算全域對象的表達式,通過 Runtime.queryObjects 反覆運算 JavaScript 棧並查找具有給定原型的所有物件(可用於計算原型鏈中某處具有相同原型的所有物件,衡量 JavaScript 記憶體洩漏)。

除了上面介紹的這些,還有 Network 可以分析網路相關的性能,以及其他可能涉及 DOM 節點、JS 執行等各種各樣的數據分析,更多的可能需要大家自己去研究了。

### 自動化性能分析

通過使用 Chrome DevTools 協定,我們可以獲取 DevTools 提供的很多數據,包括網路數據、性能數據、運行時數據。

對於如何使用該協議,其實已經有很多大神針對這個協定封裝出不同語言的庫,包括 Node.js、Python、Java等,可以根據需要在 awesome-chrome-devtools 這個專案中找到。

至於我們到底能拿到怎樣的數據,可以做到怎樣的自動化程度,就不在本文里講述啦,後面有機會再開篇文章詳細講講。

# 參考

# 結束語

前端性能分析相關的文章不算多,而由於性能分析本身的場景就跟業務特性結合比較緊密,可以用來借鑒的內容、較統一的解決方案也不多。 而性能的監控、自動化等方向的介紹比較少,也希望這篇文章能給到你們一些方向吧~

檢視Github有更多內容噢: github.com/godbasin

你也可以來我的前端遊樂場看看: godbasin.com/

想了解更多關於 Facebook 與 Google 廣告投放?

Google 出品網站性能質量及錯誤分析工具

自建站賣家如何提升網站流量? 小海總結推薦5款谷歌SEO工具