Web性能指標模型
一、RAIL 模型
RAIL 是 Response、Animation、Idle 和 Load 的首字母縮寫谨究,是一種由 Google Chrome 團隊于 2015 年提出的性能模型,用于提升瀏覽器內的用戶體驗和性能泣棋。
-
Response(響應):在
內處理事件
目標:在 100 ms內完成由用戶輸入發(fā)起的轉換胶哲,讓用戶感覺交互是即時的。
響應.png -
Animatio(動畫): 在
內生成一幀潭辈,目的為流暢的視覺效果
在 10 毫秒或更短的時間內生成動畫的每一幀鸯屿。從技術上來講澈吨,每幀的最大預算為 16 ms(1000 ms/每秒 60 幀≈16 ms),但是寄摆,瀏覽器需要大約 6 ms速來渲染一幀谅辣,因此,準則為每幀 10ms婶恼。 -
Idle(空閑):最大限度增加空閑時間
最大限度增加空閑時間以提高頁面在 50 ms內響應用戶輸入的幾率 -
Load(加載):在5s內交付并實現(xiàn)可交互
目前桑阶,對于,在使用速度較慢 3G 連接的中端移動設備上勾邦,理想的目標是在
或更短的事件內實現(xiàn)交互
對于后續(xù)加載蚣录,理想的目標是在內加載頁面。
二检痰、基于用戶體驗的性能指標
基于用戶體驗的核心指標 是 Google 在 web.dev 提出的
1. FCP (First Contentful Paint, 首次內容繪制)
含義
首次內容繪制 (FCP) 指標測量頁面從開始加載到頁面內容的任何部分在屏幕上完成渲染的時間包归。對于該指標,"內容"指的是文本铅歼、圖像(包括背景圖像)公壤、<svg>元素或非白色的<canvas>元素。
指標
測量方式
- web-vitals
import {getFCP} from 'web-vitals';
// 當 FCP 可用時立即進行測量和記錄椎椰。
getFCP(console.log);
- lighthouse
- chrome 開發(fā)者工具
優(yōu)化方案 ?
- 消除阻塞渲染的資源
- 縮小 CSS
- 移除未使用的 CSS
- 預連接到所需的來源
- 減少服務器響應時間 (TTFB)
- 避免多個頁面重定向
- 預加載關鍵請求
- 避免巨大的網(wǎng)絡負載
- 使用高效的緩存策略服務靜態(tài)資產(chǎn)
- 避免 DOM 過大
- 最小化關鍵請求深度
- 確保文本在網(wǎng)頁字體加載期間保持可見
2. LCP (Largest Contentful Paint, 最大內容繪制)
含義
最大內容繪制 (LCP) 指標會根據(jù)頁面首次開始加載的時間點來報告可視區(qū)域內可見的最大圖像或文本塊完成渲染的相對時間厦幅。
指標
測量方法
import {getLCP} from 'web-vitals';
// 當 LCP 可用時立即進行測量和記錄。
getLCP(console.log);
影響因素
- 的服務器響應速度
- JavaScript 和 CSS 渲染阻塞
- 資源加載時間
- 客戶端渲染
優(yōu)化方案?
- 使用 PRPL 模式做到即時加載
- 優(yōu)化關鍵渲染路徑
- 優(yōu)化您的 CSS
- 優(yōu)化您的圖像
- 優(yōu)化網(wǎng)頁字體
- 優(yōu)化您的 JavaScript(針對客戶端渲染的網(wǎng)站)
3. FID (First Input Delay慨飘,首次輸入延遲)
含義
FID 測量從用戶第一次與頁面交互(例如當他們單擊鏈接确憨、點按按鈕或使用由 JavaScript 驅動的自定義控件)直到瀏覽器對交互作出響應,并實際能夠開始處理事件處理程序所經(jīng)過的時間瓤的。
- 上方的可視化圖表中顯示的是一個頁面休弃,該頁面正在發(fā)出數(shù)個網(wǎng)絡請求來獲取資源(多為 CSS 和 JS 文件),這些資源下載完畢后圈膏,會在主線程上進行處理塔猾。這就導致主線程會階段性地處于忙碌狀態(tài)(在圖中表示為米黃色任務塊)
- 較長的首次輸入延遲通常發(fā)生在首次內容繪制 (FCP)和Time to Interactive 可交互時間 (TTI)之間,因為在此期間稽坤,頁面已經(jīng)渲染出部分內容丈甸,但交互性還尚不可靠。
- 如果用戶在最長的任務剛開始時就嘗試與頁面進行交互尿褪,因為輸入發(fā)生在瀏覽器正在運行任務的過程中睦擂,所以瀏覽器必須等到任務完成后才能對輸入作出響應。瀏覽器必須等待的這段時間就是這位用戶在該頁面上體驗到的 FID 值杖玲。
指標
測量方法
import {getFID} from 'web-vitals';
// 當 FID 可用時立即進行測量和記錄顿仇。
getFID(console.log);
優(yōu)化方案?
4. TTI (Time to Interactive, 可交互時間)
含義
TTI 指標測量頁面從開始加載到主要子資源完成渲染,并能夠快速、可靠地響應用戶輸入所需的時間
- ① 先進行First Contentful Paint 首次內容繪制 (FCP)夺欲。
- ② 沿時間軸正向搜索時長至少為 5 秒的安靜窗口跪帝,其中,安靜窗口的定義為:沒有長任務且不超過兩個正在處理的網(wǎng)絡 GET 請求些阅。
- ③ 沿時間軸反向搜索安靜窗口之前的最后一個長任務,如果沒有找到長任務斑唬,則在 FCP 步驟停止執(zhí)行市埋。
- ④ TTI 是安靜窗口之前最后一個長任務的結束時間(如果沒有找到長任務,則與 FCP 值相同)恕刘。
指標?
TTI指標(單位:秒) | 顏色編碼 |
---|---|
0-3.8 | 綠色(快速) |
3.9-7.3 | 橙色(中等) |
>7.3 | 紅色(慢) |
優(yōu)化方案
- 縮小 JavaScript
- 預連接到所需的來源
- 預加載關鍵請求
- 減少第三方代碼的影響
- 最小化關鍵請求深度
- 減少 JavaScript 執(zhí)行時間
- 最小化主線程工作
- 保持較低的請求數(shù)和較小的傳輸大小
5. TBT (Total Blocking Time, 總阻塞時間)
含義
總阻塞時間 (TBT) 指標測量First Contentful Paint 首次內容繪制 (FCP)與Time to Interactive 可交互時間 (TTI)之間的總時間缤谎,這期間,主線程被阻塞的時間過長褐着,無法作出輸入響應坷澡。
長任務:在主線程上運行超過 50 ms的任務。
雖然在主線程上運行任務的總時間為 560(250+90+35+30+155 = 560) 毫秒含蓉,但其中只有 345(200+40+105 = 345) 毫秒被視為阻塞時間
指標?
TBT指標(單位:毫秒) | 顏色編碼 |
---|---|
0-200 | 綠色(快速) |
200-600 | 橙色(中等) |
>600 | 紅色(慢) |
優(yōu)化方案
6. CLS (Cumulative layout shift, 累計布局偏移)
含義
測量頁面在開始加載和其生命周期狀態(tài)變?yōu)殡[藏期間發(fā)生的所有意外布局偏移的累積分數(shù)频敛。
每當一個可見元素的位置從一個已渲染幀變更到下一個已渲染幀時,就發(fā)生了布局偏移馅扣。
指標
布局偏移分數(shù) = 影響分數(shù) * 距離分數(shù)
- 影響分數(shù)是0.75(紅色虛線矩形框表示兩幀中元素的可見區(qū)域集合斟赚,在本示例中,該集合占總可視區(qū)域的 75%差油,因此其影響分數(shù)為0.75 拗军。)
- 距離分數(shù)是0.25 (最大的可視區(qū)域尺寸維度是高度,不穩(wěn)定元素的位移距離為可視區(qū)域高度的 25%蓄喇,因此距離分數(shù)為 0.25)
- 所以布局偏移分數(shù)是0.75 * 0.25 = 0.1875 发侵。
測量方法
import {getCLS} from 'web-vitals';
// 在所有需要匯報 CLS 的情況下
// 對其進行測量和記錄。
getCLS(console.log);
優(yōu)化方案?
- 始終在您的圖像和視頻元素上包含尺寸屬性妆偏,或者通過使用CSS 長寬比容器之類的方式預留所需的空間刃鳄。
- 除非是對用戶交互做出響應,否則切勿在現(xiàn)有內容的上方插入內容楼眷。
- 首選轉換動畫铲汪,而不是觸發(fā)布局偏移的屬性動畫
7. SI
含義
指標
測量方法
優(yōu)化方案
三、Web vitals
Web Vitals罐柳,即 Google 給的定義是一個良好網(wǎng)站的基本指標(Essential metrics for a healthy site)
Chorme network下Finish掌腰、DOMContentLoaded, Load參數(shù)含義
- Finish: 頁面上所有 http 請求發(fā)送到響應完成的時間张吉。如果頁面加載完后齿梁,觸發(fā)了http請求,那么該時間會變更。
-
DOMContentLoaded:DOM 樹構建完成勺择。即 HTML 頁面由上向下解析 HTML 結構到末尾的封閉標簽·
</html>
创南。但像 <img> 和樣式表之類的外部資源
可能尚未加載完成。 - Load:瀏覽器不僅加載完成了 HTML省核,還加載完成了所有外部資源:圖片稿辙,樣式等
Finish 與 DOMContentLoaded 和 Load 并無直接關系
DOMContentLoaded 觸發(fā)時機
-
無JS和CSS
無JS和CSS.jpg -
只有CSS
只有CSS.jpg -
有JS和CSS
有JS和CSS.jpg
外部樣式表不會影響 DOM,因此 DOMContentLoaded 不會等待它們气忠。
但這里有一個陷阱邻储。如果在樣式后面有一個腳本,那么該腳本必須等待樣式表加載完成:
<link type="text/css" rel="stylesheet" href="style.css">
<script>
// 在樣式表加載完成之前旧噪,腳本都不會執(zhí)行
alert(getComputedStyle(document.body).marginTop);
</script>
首屏時間和白屏時間
白屏時間
白屏時間 = 地址欄輸入網(wǎng)址后回車 - 瀏覽器出現(xiàn)
影響白屏時間的因素:網(wǎng)絡吨娜,服務端性能,前端頁面結構設計淘钟。
通常認為瀏覽器開始渲染 <body> 或者解析完 <head> 的時間是白屏結束的時間點宦赠。
首屏時間
首屏時間 = 地址欄輸入網(wǎng)址后回車 - 瀏覽器
影響首屏時間的因素:白屏時間,資源下載執(zhí)行時間米母。
關于首屏時間是否包含圖片加載網(wǎng)上有不同的說法勾扭。
Performance Api
Navigation Timing Level 1
字段 | 含義 |
---|---|
memory | |
jsHeapSizeLimit | 上下文內可用堆的最大體積 |
totalJSHeapSize | 已分配的堆體積 |
usedHeapSize | 當前js堆活躍段的體積 |
navigation | |
redirectCount | 重定向次數(shù) |
type | 如何導航至此頁面: 0:點擊鏈接,書簽爱咬,表單提交尺借,腳本操作,url中直接輸入地址 1:點擊刷新或者Location.reload() 2:瀏覽器歷史記錄精拟,前進后退 255:其他方式 |
timing | |
connectEnd | HTTP(TCP) 完成建立連接的時間(完成握手)燎斩,如果是持久連接,則與 fetchStart 值相 注意如果在傳輸層發(fā)生了錯誤且重新建立連接蜂绎,則這里顯示的是新建立的連接完成的時間 注意這里握手結束栅表,包括安全連接建立完成、SOCKS 授權通過 |
connectStart | HTTP(TCP) 開始建立連接的時間师枣,如果是持久連接怪瓶,則與 fetchStart 值相等 注意如果在傳輸層發(fā)生了錯誤且重新建立連接,則這里顯示的是新建立的連接開始的時間 |
domComplete | DOM 樹解析完成践美,且資源也準備就緒的時間洗贰,Document.readyState 變?yōu)?complete,并將拋出 readystatechange 相關事件 |
domContentLoadedEventEnd | DOM 解析完成后陨倡,網(wǎng)頁內資源加載完成的時間(如 JS 腳本加載執(zhí)行完畢)敛滋,觸發(fā)DOMContentLoaded事件 |
domContentLoadedEventStart | DOM 解析完成后,網(wǎng)頁內資源加載開始的時間 在 DOMContentLoaded 事件拋出前發(fā)生 |
domInteractive | 完成解析 DOM 樹的時間兴革,Document.readyState 變?yōu)?interactive绎晃,并將拋出 readystatechange 相關事件 注意只是 DOM 樹解析完成蜜唾,這時候并沒有開始加載網(wǎng)頁內的資源 |
domLoading | 開始解析渲染 DOM 樹的時間,此時 Document.readyState 變?yōu)?loading庶艾,并將拋出 readystatechange 相關事件 |
domainLookupEnd | DNS 域名查詢完成的時間袁余,如果使用了本地緩存(即無 DNS 查詢)或持久連接,則與 fetchStart 值相等 |
domainLookupStart | DNS 域名查詢開始的時間咱揍,如果使用了本地緩存(即無 DNS 查詢)或持久連接颖榜,則與 fetchStart 值相等 |
fetchStart | 瀏覽器準備好使用 HTTP 請求抓取文檔的時間,這發(fā)生在檢查本地緩存之前 |
loadEventEnd | load 事件的回調函數(shù)執(zhí)行完畢的時間 |
loadEventStart | load 事件發(fā)送給文檔述召,也即 load 回調函數(shù)開始執(zhí)行的時間 注意如果沒有綁定 load 事件朱转,值為 0 |
navigationStart | 在同一個瀏覽器上下文中,前一個網(wǎng)頁(與當前頁面不一定同域)unload 的時間戳积暖,如果無前一個網(wǎng)頁 unload ,則與 fetchStart 值相等 |
redirectEnd | 最后一個 HTTP 重定向完成時的時間怪与。有跳轉且是同域名內部的重定向才算夺刑,否則值為 0 |
redirectStart | 第一個 HTTP 重定向發(fā)生時的時間。有跳轉且是同域名內的重定向才算分别,否則值為 0 |
requestStart | HTTP 請求讀取真實文檔開始的時間(完成建立連接)遍愿,包括從本地讀取緩存 連接錯誤重連時,這里顯示的也是新建立連接的時間 |
responseEnd | HTTP 響應全部接收完成的時間(獲取到最后一個字節(jié))耘斩,包括從本地讀取緩存 |
responseStart | HTTP 開始接收響應的時間(獲取到第一個字節(jié))沼填,包括從本地讀取緩存 |
secureConnectionStart | HTTPS 連接開始的時間,如果不是安全連接括授,則值為 0 |
unloadEventEnd | 和 unloadEventStart 相對應坞笙,返回前一個網(wǎng)頁 unload 事件綁定的回調函數(shù)執(zhí)行完畢的時間戳 |
unloadEventStart | 前一個網(wǎng)頁(與當前頁面同域)unload 的時間戳,如果無前一個網(wǎng)頁 unload 或者前一個網(wǎng)頁與當前頁面不同域荚虚,則值為 0 |
Navigation Timing Level 2
Level 2標準廢棄了level 1的timing和navigation這兩個接口薛夜,取而代之的是定義了 PerformanceNavigationTiming 對象
window.performance.getEntriesByType("navigation")[0]
常用來計算的參數(shù)
TTFB 首字節(jié)時間
TTFB(Time To First Byte):從發(fā)送請求到數(shù)據(jù)返回第一個字節(jié)所消耗時間
const { responseStart, requestStart } = performance.timing
const TTFB = responseStart - requestStart
FP 首次繪制
FP(First Paint) :第一個像素繪制到頁面上的時間
const paint = performance.getEntriesByType('paint')
const FP = paint[0].startTime
FCP 首次內容繪制
FCP (First Contentful Paint) 首次內容繪制 標記瀏覽器渲染來自 DOM 第一位內容的時間點,該內容可能是文本版述、圖像梯澜、SVG 甚至 元素
const paint = performance.getEntriesByType('paint')
const FCP = paint[1].startTime
FMP 首次有效繪制
FMP(First Meaningful Paint) 首次有效繪制: 例如,在 YouTube 觀看頁面上渴析,主視頻就是主角元素.
圖片可以沒加載完成晚伙,但整體的骨架已經(jīng)加載完成了。
1秒內完成FMP的概率超過80%俭茧,那就代表這個網(wǎng)站是一個性能較好的網(wǎng)站
let FMP = 0
const performanceObserverFMP = new PerformanceObserver((entryList, observer) => {
const entries = entryList.getEntries()
observer.disconnect()
FMP = entries[0].startTime
})
// 需要在元素中添加 elementtiming="meaningful"
performanceObserverFMP.observe({ entryTypes: ['element'] })
TTI 可交互時間
TTI (Time to Interactive) 可交互時間: DOM樹構建完畢咆疗,可以綁定事件的時間
const { domInteractive, fetchStart } = performance.timing
const TTI = domInteractive - fetchStart
LCP 最大內容渲染
let LCP = 0
const performanceObserverLCP = new PerformanceObserver((entryList, observer) => {
const entries = entryList.getEntries()
observer.disconnect()
LCP = entries[entries.length - 1].startTime
})
performanceObserverLCP.observe({ entryTypes: ['largest-contentful-paint'] })
DCL
DCL (DomContentloaded): 當 HTML 文檔被完全加載和解析完成之后,DOMContentLoaded 事件被觸發(fā)恢恼,無需等待樣式表民傻、圖像和子框架的完成加載
const { domContentLoadedEventEnd, fetchStart } = performance.timing
const DCL = domContentLoadedEventEnd - fetchStart
L 全部加載完畢
L (on/Load), 當依賴的資源(圖片、文件等), 全部加載完畢之后才會觸發(fā)
const { domContentLoadedEventEnd, fetchStart } = performance.timing
const DCL = domContentLoadedEventEnd - fetchStart
FID 首次輸入延遲
FID (First Input Delay) 首次輸入延遲: 指標衡量的是從用戶首次與您的網(wǎng)站進行交互(即當他們單擊鏈接,點擊按鈕等)到瀏覽器實際能夠訪問之間的時間
let FID = 0
const performanceObserverFID = new PerformanceObserver((entryList, observer) => {
const entries = entryList.getEntries()
observer.disconnect()
FID = entries[0].processingStart - entries[0].startTime
})
performanceObserverFID.observe({ type: ['first-input'], buffered: true })
瀏覽器發(fā)起一個HTTP 請求過程
Chrome限制每個域名最多執(zhí)行6個TCP連接漓踢。如果您一次請求十二個資源牵署,前6個將開始,后6個將排隊喧半。一旦其中一個請求完成奴迅,隊列中的第一個請求項目將開始其請求過程。
-
Queuing
(排隊)排隊時間 -
Stalled
(停滯)發(fā)送請求之前等待的時間 -
DNS lookup
(DNS查找)挺据, -
initial connection
(初始連接) -
SSL handshake
(SSL握手) -
Request sent
(請求發(fā)送)發(fā)出網(wǎng)絡請求所花費的時間 -
Waiting
(等待)(到開始下載第一個字節(jié)的時間(TTFB))等待初始響應所花費的時間 -
Content Download
(內容下載)接收響應數(shù)據(jù)所花費的時間
TTFB就是等待第一個響應字節(jié)的時間取具,建議在200ms以下,以下情況可能會導致高TTFB(延遲):
- 客戶端和服務器之間的網(wǎng)絡條件差扁耐,
- 要么暇检,服務器端程序響應很慢。
實驗數(shù)據(jù)收集工具
Lihgthouse
chrome 瀏覽器婉称,F(xiàn)12打開開發(fā)者工具块仆,ctrl + shift + P
搜索Lighthouse可以調出此工具
參數(shù)含義
參考
首屏時間(FCP) VS 白屏時間(FP)
網(wǎng)站性能指標這么多,你到底選對了嗎王暗?
使用 RAIL 模型衡量性能
頁面生命周期:DOMContentLoaded悔据,load,beforeunload俗壹,unload
首屏時間與domContentLoaded觸發(fā)時機的關系
Web 性能優(yōu)化-首屏和白屏時間
控制臺了解認知---network
初探performance-監(jiān)控網(wǎng)頁與程序性能
前端性能的幾個基礎指標
關于Web頁面全鏈路性能優(yōu)化指南
Navigation Timing
Using Navigation Timing APIs to understand your webpage
前端頁面性能優(yōu)化總結