前端性能優化到底該怎麼做(上)— 開門見山

作者:熊的貓

https://juejin.cn/post/7137058832592666655

前言

前端性能優化 又是個聽起來很高大上的詞,確實是的,因爲它需要 高在性能,大在範圍 ,所幸很多大佬都已經輸出了很多高質量的內容供大家參考,作者最近也在學習和了解這方面的內容,對如下文中的一些理解若有不當之處,可在評論區討論!!!

前端性能優化這個內容打算分爲 上下兩篇,本來打算一篇寫完,但發現前置知識部分已經佔了 3000+ 文字,因此本篇文章主要還是講解一些必要了解的前置內容。

前端性能優化到底是在優化什麼?

其實前端性能優化核心就是兩點:

而這些核心內容都可以從下面這個老生常談的問題中延伸開來。

從輸入 URL 到頁面加載完成發生了什麼?

相信到現在爲止,大家對這個問題的回答可以說是能夠做到滔滔不絕了吧(如果不能,請忽略)!不過每個人回答的方向和重點應該都不一樣,比如之前在 B 站winter 大佬對這個問題的看法和解析的角度是更深、更廣的。

在這還是要簡單的總結一下核心內容:

以上任意一點都可進行無限擴展、延伸,但點到爲止纔是現在真正需要的。

性能指標

RAIL 模型

Google 爲前端頁面性能的評估提出了 RAIL 模型,核心內容如下:

常規性能指標

性能指標其實有不少的內容,但在這我們指列舉比較常用的幾種:

性能指標工具

通過上述內容瞭解了性能指標的相關內容和一些閥值,那麼接下來的問題是我們怎麼獲取一個網站的具體性能指標數據呢?

爲了方便還是得使用工具或者說是 API,當然可以 自定義頁面性能指標 的計算方式,比如有些就是通過計算當前頁面 DOM總節點數嵌套層級 來計算一個網站的分數等,這裏就不再額外介紹。

Performance 面板(Google)

具體參數介紹可以看 Big shark@LX[1] 大佬的文章,裏面介紹的非常詳細,這裏只列舉一些核心點。

火焰圖

Networks 指標

通過 Networks 指標可以查看到對應服務器加載資源的相關信息:

可以將鼠標 移動點擊 到具體的請求上查看加載時間和加載速度,如下:

鼠標移入:

鼠標點擊:

Frames 指標

通過 Frames 指標可以查看頁面每一幀渲染時 CPU 所消耗的時間和持續時間 Duration 的信息,如下:

圖一:

圖二:

Timings 指標

通過 Timings 指標可以查看在上面列舉的一些性能指標的值,如下:

Main 指標

Main 指標包含了加載過程的三個階段:

Lighthouse 面板(Google)

Performance 面板最大的優點就是各種數據信息非常的全,但這也是它最大的缺點,數據信息龐大到需要自行過濾,對於不熟悉的開發者來說,還是需要一定的學習成本的。

相反,Lighthouse 面板中的信息就相對簡潔一些,除了檢測結果以外,還會提供對應的改進方案,真是考慮得妥妥的,主要檢測五個方面的內容:

可以通過 Analyze page load 按鈕來開始對頁面應用進行檢測,這裏以掘金首頁爲例:

下面以 Performance 性能 爲例簡單看一下具體包含的內容,由於篇幅有限,其他內容可自行測試並進行閱讀。

Performance 性能(舉一反三)

從性能指標的數據來看,只有 累積佈局偏移(Cumulative Layout Shift, CLS) 滿足要求,其他指標顯示 黃色紅色,意味着仍有改進的空間,特別是 首屏時間2.9s 已經是超過了對應的閾值 2.5s

性能指標數據如下圖所示:

甚至還提供了對應的診斷結果,比如提到的圖片沒有設置對應的寬高:

Using the Node CLI

甚至還支持在 Node 環境運行,感興趣的自行去 npm 中查看 文檔[2] 即可,這裏不過多介紹。

性能指標數據收集

上述性能指標工具的能力已經足夠強大,覆蓋信息也很全面,但如果我們需要將頁面性能指標數據收集並上報又該怎麼辦呢?

首先排除的肯定是通過 性能指標工具 的方式來收集,一旦要檢測性能指標數據意味着得是不同的客戶端統計數據的結果合集(除非你願意一臺一臺客戶端來手動記錄和收集數據,呸,你願意你領導還不願意呢),最理想的方式當然是自動收集和上報,那就意味着這應該是代碼要乾的活!!!

既然有這樣的需求,那麼必定有對應的解決方案,您接着往下看!

Performance API

實際上在瀏覽器端的全局對象 window 上有一個名爲 performance 的屬性,它是一個用於支持 IE9 以上及 webkit 內核瀏覽器中用於記錄頁面 加載解析 過程中關鍵時間點的機制,其兼容性在 caniuse[3] 中的表現如下:

下面就簡單介紹一下和 window.performance 相關一些核心屬性和方法。

performance.timing 屬性

performance.timing 屬性中提供了很多關鍵的時間信息,我們可以通過這些時間節點來簡單的計算出需要的性能指標數據(不一定準確),計算方式如:

const {
 domainLookupStart,
 domainLookupEnd,
 navigationStart,
 loadEventEnd,
 responseStart,
 responseEnd,
 connectStart,
 connectEnd,
 redirectStart,
 redirectEnd,
 domContentLoadedEventEnd,
 domComplete,
} = performance.timing

// DNS 查詢時間
DNS = domainLookupEnd - domainLookupStart

// TCP 建立連接時間
TCP = connectEnd - connectStart

// 頁面重定向時間
Redirect = redirectEnd - redirectStart

// 首字節到底時間
TTFB = responseStart - navigationStart

// 首次渲染時間
FP = responseStart - navigationStart

// DOM 解析時間
DOM = domComplete - responseEnd

// 首屏時間
LCP = loadEventEnd - navigationStart

performance.getEntries() 方法

performance.getEntries() 方法可以獲取所有資源請求的時間數據,如下:

點擊可查看具體的資源信息,其他屬性和上述內容有重複,就不在額外介紹計算方式了,具體如下:

performance.now() 方法

performance.now() 方法可以精確計算程序執行時間,它會返回以微秒(百萬分之一秒)爲單位的時間,即更加精準,這也是它和 Date.now() 是不同點:

Web Vitals

web-vitals[4] 庫是 Google 推出的一個小型(約 1.5K)模塊化庫,用於測量真實用戶的所有 Web Vitals 相關的指標,其重要核心指標信息如下(一圖勝千言):

接下來,讓我們通過 npx create-react-app my-react-app 來創建一個 react 項目,然後觀察一下它的項目結構:

是不是超級顯眼的 reportWebVitals.js,在進入文件查看你會發現我們需要的核心性能指標都在裏面:

最後

前端性能優化這個內容是之前一直打算要寫的,終歸知識有所欠缺,到現在也算是邊學習邊輸出中,下一篇就針對性能優化的方案進行一些總結!!!

參考資料

[1]

Big shark@LX: https://juejin.cn/post/7052918009555320839#heading-14

[2]

文檔:https://www.npmjs.com/package/lighthouse

[3]

caniuse:https://caniuse.com/?search=performance

[4]

web-vitals: https://www.npmjs.com/package/web-vitals

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