深入淺出 Performance 工具 - API

概述


日常開發任務中,對於性能優化或多或少會接觸到一些內容,可能也參照過雅虎 35 條軍規 [1] 進行過相關的性能優化,但是具體的優化結果以及實際的頁面速度如何,我們怎麼去看呢?以及出現性能問題了,我們如何通過現有工具進行定位 & 解決?也就是今天我要給大家介紹的內容主題了「Performance」,主題偏向工具介紹,主要從下面 4 個方面介紹今天的內容。

Chrome Performance 工具使用

Chrome 中 Performance 可以在上圖中看到,主要分了幾個板塊

控制面板(Controls)

開啓記錄,停止記錄,配置記錄期間需要記錄的內容。

操作主要分了 2 個區域,操作 1 區從左到右依次是 "Record/Stop"、"Reload" 和 "Clear",

操作 2 區可以選擇報告展示內容,從左到右依次是 Screenshots、Memory、Web Vitals

概覽面板(Overview)

主要是對頁面表現行爲的一個概述,區域由三個圖形記錄組成。

火焰圖(Flame Chart)

其實這裏我們主要需要關注 Main,因爲他是主線程的一個執行情況的監控。點開後,我們可以看當前線程裏面一些任務的執行堆棧耗時,我們需要重點關注一些標紅(也就是有較高耗時)的任務。

詳細信息(Detail)

當有具體事件被選擇時,該面板展示這個事件的更多詳細信息。如果沒有事件被選擇,該面板展示當前所選時間段的一些信息。詳細面板支持精確到毫秒級別的分析,詳細面板主要分了

Performance Api 監測網頁性能

除了瀏覽器爲我們提供的 Performance 性能檢測調試工具外,W3C 也定義了一套 Performance 標準,各個瀏覽器廠商基於標準提供了監控網絡性能的一系列基礎 Api,這些 Api 可以提供檢測白屏時間、首屏時間、用戶可操作的時間節點,頁面總下載的時間、DNS 查詢的時間、TCP 鏈接的時間等。我們完全可以利用這個搭建一個簡易的性能監控工具,當然監控系統包含了數據採集 -> 數據存儲 -> 清洗 -> 監控幾個過程,不過目前我們這裏簡單運用一下 Performance Api 就只考慮採集階段。

提供的能力

  1. 屬性篇

performance 的所有 Api&property 掛載在 window 下面的 performance 屬性中,可以看到目前提供的一系列屬性,關於各個屬性的介紹,參照網上對 aip 的解釋,有大量資料可供查詢。

如上圖所展現,performance 包含三個對象,分別爲 memory、navigation、timing

  1. 方法篇

如上圖,截取的圖片,Performance 提供了一些,這裏我主要介紹一下 now() 方法和 getEntries() 方法。其他的網上資料也比較多和全,可以查閱 https://juejin.cn/post/6844903801518981133#heading-54

我們可以用這個方法來衡量函數執行的時間,達到監控函數執行效率的效果

`const fun = () ={

// do something

}

const startExcuteTime = window.performance.now();

fun();

const endExcuteTime = window.performance.now();

console.log("fun 函數執行了" + (endExcuteTime - startExcuteTime) + "毫秒.")  
`

點開數組中的元素,每個元素詳細記錄了資源請求關鍵節點的時間,所以我們完全可以利用這個來實現對資源的請求監控。

更多 Api 細節,可以參考司內文章再看一次 Performance 接口 [2]

簡單實現指標計算

一個監控系統大致可以分爲這個下面階段,我們這裏就先關注一下數據的採集階段。數據採集階段設計到兩點,一個是數據的蒐集,一個是數據的上報。

下面是 Slardar 源碼截圖,可以看到他們上報監控數據優先採用的 sendBecan,降級策略爲 XHR 請求。

可以通過 performance api 來實現我們經常關注的一些指標的計算和上報

` 重定向耗時  = redirectEnd - redirectStart;

DNS 查詢耗時  = domainLookupEnd - domainLookupStart;

TCP 鏈接耗時  = connectEnd - connectStart;

HTTP 請求耗時  = responseEnd - responseStart;

解析 dom 樹耗時  = domComplete - domInteractive;

白屏時間  = responseStart - navigationStart;

DOMready 時間  = domContentLoadedEventEnd - navigationStart;

onload 時間  = loadEventEnd - navigationStart;
`

現存的一些網頁性能檢測工具

除了前面兩種方式能夠檢測頁面性能外,還有一些三方的工具 or 平臺爲我們提供了檢測能力。

下面是使用 LightHouse 的截圖,Lighthouse 生成的不僅僅是一些性能相關的數據,他除了能給我們提供頁面性能檢測外,還爲我們列出了一系列的優化建議,我們對網站或者頁面的優化,可以參照建議一步步進行優化。

提供組件級別的渲染分析 React 性能測量和分析 [3]React Profiler 介紹 – React Blog[4]

Performance 工具小試

學浪老師端項目代碼目前跑在兩個大的宿主環境中「CEF 套殼」「瀏覽器」,項目一期的時候,整體項目是採用的單入口多路有方式,並且來說項目的打包也沒有優化,整體上呈現出

上面的一系列問題,導致學浪整體頁面加載速度非常的慢,後續學浪側專門組織了一次大的重構優化,進行了項目入口的拆分 & 打包過程的的拆分,整體上現的學浪項目結構是多入口多路由,且區分宿主環境的。從目前的表現來看,頁面的加載速度相對於以前提升了非常多。目前的加載時長度在我當前網絡情況下 DomContentLoad 大概在 2S 左右

是否還有優化空間,將頁面加載時間降得更低?我們可以通過 Performance 的 NetWork 火焰圖看看到底是哪些文件的加載耗時長,延長了 DomContentLoad 觸發時機。首先 DomContentLoad 事件觸發影響因素有 html 下載、dom 解析、js 腳本下載 & 執行,都會影響 DomContentLoad 觸發。

通過觀察 NetWork 的情況,很明顯看到 DCL 的時機,在一個 encoding.js 文件加載完成後,再觸發的,而這個文件的加載時間長達 2.13s,可謂是佔據了首頁加載的 80% 左右的時間,那麼就想如何優化這個腳本的加載時長?有幾種思路

找到了原因和思路,於是開始先對文件背景溯源,發現由於這個文件是爲了處理一些教室內 sdk 在不同瀏覽器內的 pollfiy,但是目前因爲通過階段一的大包 & 入口的拆分,教室內 sdk 的相關資源不會出現在瀏覽器環境加載了,因此在瀏覽器環境內實際不再使用,godless 我們可以直接刪除,看下效果。(實際看 encoding.js 文件也是沒有壓縮過的,如果實際文件有在用,我們可以採取使用壓縮文件)

整體上 DCL 的觸發時間由 2.13s 降低爲 972ms,效果還是比較明顯的。通過一個很小的分析案例 + 很小的優化說明下 Performance 面板中相關模塊的使用。

總結

本文主要介紹了通過工具的使用來定位性能問題以及通過 Performance Api 來自己做一些指標的計算統計,目前公司內的 Sladar 已經爲我們提供了比較全面的數據分析,但是對於一些定位頁面性能的基礎工具和基礎能力的瞭解對於日常的工作中也是有幫助的

參考資料

[1] 雅虎 35 條軍規:https://juejin.cn/post/6844903657318645767

[2] 再看一次 Performance 接口:https://bytedance.feishu.cn/docs/doccnZoHj24ab8HVh42aQEowZGh#

[3]React 性能測量和分析:https://juejin.cn/post/6844903869378641933#heading-4

[4]React Profiler 介紹 – React Blog:https://zh-hans.reactjs.org/blog/2018/09/10/introducing-the-react-profiler.html

[5]React 性能測量和分析:https://juejin.cn/post/6844903869378641933#heading-4

[6]React Profiler 介紹 – React Blog:https://zh-hans.reactjs.org/blog/2018/09/10/introducing-the-react-profiler.html

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/d-vudj57Hyf8dQXxkYkIxw