如何通過DevTools工具實現Web前端性能自動化分析?

導語 | 大型項目最容易遇到性能問題,一般來說當我們遇到性能瓶頸的時候,纔會開始去進行相應的分析。分析的方向除了與業務本身特點相關之外,常見的還可以藉助一些工具來發現問題。下文就將和大家一起探討前端性能分析該怎樣走?文章作者:王貝珊,騰訊前端開發工程師。

一、前端性能分析工具

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

  • 時間:常見耗時,如頁面加載耗時、渲染耗時、網絡耗時、腳本執行耗時等;
  • 空間:資源佔用,包括 CPU 佔用、內存佔用、本地緩存佔用等。

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

1. Lighthouse

Lighthouse [2] 的前身是 Chrome DevTools 面板中的 Audits。在 Chrome 60 之前的版本中, 這個面板只包含網絡使用率和頁面性能兩個測量類別,從 Chrome 60 版本開始, Audits 面板已經被 Lighthouse 的集成版取代。

而在最新版本的 Chrome 中,則需要單獨安裝 Lighthouse 拓展程序來使用,也可以通過腳本來使用。

(1)架構

下面是 Lighthouse 的組成部分:

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

(2)主要功能

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

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

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

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

2. Performance 面板

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

(1)使用步驟

Performance 面板功能特別多,這裏簡單說一下使用的步驟:

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

(2)主要功能

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

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

具體要怎麼定位某些性能瓶頸,可以參考官方文檔系列文檔,這裏不再贅述。

(3)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)。

1. 合成監控

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

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

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

2. 真實用戶監控

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

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

而我們要做的,則是在力所能及的地方進行打點、計算、採集、上報,該過程常常需要藉助 Performance Timeline API。

將需要的數據發送到服務端,然後再對這些數據進行處理,最終通過可視化等方式進行監控。因此,真實用戶監控往往需要結合業務本身的前後端架構設計來建設,其優點也比較容易理解:

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

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

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

三、性能分析自動化

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

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

1. 使用 Lighthouse

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

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

不過由於 Lighthouse 同樣基於 CDP(Chrome DevTools Protocol),因此雖然開發成本降低了,但CDP 缺失的一些能力它也同樣會缺失。

2. Chrome DevTools Protocol

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

(1)認識 Chrome DevTools 協議

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

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

  • DevTools 將作爲 Web 應用程序,Chromium 作爲服務端提供連接。
  • 通過 HTTP 提取 HTML、JavaScript 和 CSS 文件。
  • 資源加載後,DevTools 會建立與瀏覽器的 Websocket 連接,並開始交換 JSON 消息。

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

(2)Chrome DevTools 協議域劃分

Chrome DevTools 協議具有與瀏覽器的許多不同部分(例如頁面、Service Worker 和擴展程序)進行交互的 API。該協議把不同的操作劃分爲了不同的域(domain),每個域負責不同的功能模塊。

比如DOM、Debugger、Network、Console和Performance等,可以理解爲 DevTools 中的不同功能模塊。

使用該協議我們可以:

  • 獲取 JS 的 Runtime 數據,常用的如window.performance和window.chrome.loadTimes() 等;
  • 獲取 Network 及 Performance 數據,進行自動性能分析;
  • 使用 Puppeteer [8] 的 CDPSession [9],與瀏覽器的協議通信會變得更加簡單。

(3)與性能相關的域

本文討論的主要與性能分析相關,因此這裏我們只關注和性能相關的域。

Performance

從 Performance 域中 Performance.getMetrics() 可以拿到獲取運行時性能指標包括:

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

Tracing

Tracing 域可獲取頁面加載的 DevTools 性能跟蹤。可以使用 Tracing.start 和 Tracing.stop 創建可在 Chrome DevTools 或時間軸查看器中打開的跟蹤文件。

生成的 JSON 文件如下圖所示:

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

Runtime

Runtime 域通過遠程評估和鏡像對象暴露 JavaScript 的運行時。可以通過 Runtime.getHeapUsage 獲取 JavaScript 棧的使用情況,通過 Runtime.evaluate 計算全局對象的表達式,通過 Runtime.queryObjects 迭代 JavaScript 棧並查找具有給定原型的所有對象(可用於計算原型鏈中某處具有相同原型的所有對象,衡量 JavaScript 內存泄漏)。

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

(4)自動化性能分析

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

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

四、結語

前端性能分析相關的文章不算多,而由於性能分析本身的場景跟業務特性結合比較緊密,可以用來借鑑的內容、較統一的解決方案也不多。同時性能的監控、自動化等方向的介紹也比較少。

本文主要圍繞前端性能分析工具 Chrome DevTools,介紹了其 Lighthouse 與Performance 面板的用途和使用,並在前端性能監控和性能分析自動化也探討了通用的思路和方案,最後希望這篇文章能給大家帶來一些啓發。

參考資料

[1] Chrome DevTools:

https://developers.google.com/web/tools/chrome-devtools

[2] Lighthouse:

https://github.com/GoogleChrome/lighthouse

[3] Performance :

https://developers.google.com/web/tools/chrome-devtools/evaluate-performance/reference

[4] Timeline :

https://developers.google.com/web/tools/chrome-devtools/evaluate-performance/timeline-tool?hl=zh-cn

[5] 官方說明:

https://developers.google.com/web/tools/chrome-devtools/evaluate-performance

[6] Lighthouse官方配置:

https://github.com/GoogleChrome/lighthouse/blob/master/docs/configuration.md

[7] Chrome DevTools Protocol :

https://chromedevtools.github.io/devtools-protocol/

[8] Puppeteer:

https://github.com/GoogleChrome/lighthouse/blob/master/docs/puppeteer.md

[9] CDPSession:

https://pptr.dev/#?product=Puppeteer&version=v1.13.0&show=api-class-cdpsession

[10] DevTools Timeline Viewer:

https://chromedevtools.github.io/timeline-viewer/

[11] awesome-chrome-devtools:

https://github.com/ChromeDevTools/awesome-chrome-devtools#chrome-devtools-protocol

[12] 你一定要知道的 Chrome DevTool 新功能:

https://www.zcfy.cc/article/the-new-chrome-devtool-feature-you-want-to-know-about-3318.html

[13] 前端性能分析利器-Chrome性能分析&性能監視器:

https://juejin.im/post/6844904045774110733

[14] 螞蟻金服如何把前端性能監控做到極致?

https://www.infoq.cn/article/Dxa8aM44oz*Lukk5Ufhy

[15] chrome devtools protocol——Web 性能自動化實踐介紹:

https://testerhome.com/topics/15817

[16] Web Performance Recipes With Puppeteer:

https://addyosmani.com/blog/puppeteer-recipes/#measuring-memory-leaks

本文轉載自公衆號雲加社區(ID:QcloudCommunity)。

原文鏈接

如何通過DevTools工具實現Web前端性能自動化分析?

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章