前端頁面性能指標


基本指標介紹

首次繪制(First Paint,FP)

FP 是時間線上的第一個“時間點”,是指瀏覽器從響應用戶輸入網址地址,到瀏覽器開始顯示內容的時間,簡而言之就是瀏覽器第一次發生變化的時間。

首次內容繪制(First Contentful Paint,FCP)

FCP(全稱“First Contentful Paint”,翻譯為“首次內容繪制”),是指瀏覽器從響應用戶輸入網絡地址,在頁面首次繪制文本,圖片(包括背景圖)、非白色的 canvas 或者 SVG 才算做 FCP,有些文章說 FCP 是首屏渲染事件,這其實是不對的。

可交互時間(Time to Interactive,TTI)

TTI,翻譯為“可交互時間”表示網頁第一次完全達到可交互狀態的時間點。可交互狀態指的是頁面上的 UI 組件是可以交互的(可以響應按鈕的點擊或在文本框輸入文字等),不僅如此,此時主線程已經達到“流暢”的程度,主線程的任務均不超過 50 毫秒。在一般的管理系統中,TTI 是一個很重要的指標。

最大內容繪制(Largest Contentful Paint,LCP)

LCP(全稱“Largest Contentful Paint”)表示可視區“內容”最大的可見元素開始出現在屏幕上的時間點。

首次有效繪制(First Meaning Paint, FMP) 廢棄

FMP(全稱“First Meaningful Paint”,翻譯為“首次有效繪制”表示頁面的“主要內容”開始出現在屏幕上的時間點,它以前是我們測量用戶加載體驗的主要指標。本質上是通過一個算法來猜測某個時間點可能是 FMP,但是最好的情況也只有 77%的准確率,在 lighthouse6.0 的時候廢棄掉了這個指標,取而代之的是 LCP 這個指標。

performance

performance 介紹

performance 對象是專門用來用於性能監控的對象,內置了一些前端需要的性能參數。

performance.now()方法

performance.now() 返回 performance.navigationStart 至當前的毫秒數。performance.navigationStart 是下文將介紹到的可以說是瀏覽器訪問最初的時間測量點。

performance.now(); // 24614164.599999994

performance.timing

performance.timing

performance.getEntries()方法

瀏覽器獲取網頁時,會對網頁中每一個對象(腳本文件、樣式表、圖片文件等等)發出一個 HTTP/HTTPS 請求。performance.getEntries() 方法以數組形式,返回一個 PerformanceEntry 列表,這些請求的時間統計信息,有多少個請求,返回數組就會有多少個成員。

performance.getEntriesByType('paint')

指標計算方法

首屏和白屏

白屏時間是指瀏覽器從響應用戶輸入網址地址,到瀏覽器開始顯示內容的時間,一種比較簡單的做法是在 body 標簽之前獲取當前時間 - performance.timing.navigationStart,或者直接獲取 performance 中關於 paint 的兩個數據,都可以直接作為白屏數據,這兩個數據一般差別不大。

首次繪制 FP 包括了任何用戶自定義的背景繪制,它是首先將像素繪制到屏幕的時刻。

首次內容繪制 FCP 是瀏覽器將第一個 DOM 渲染到屏幕的時間。該指標報告了瀏覽器首次呈現任何文本、圖像、畫布或者 SVG 的時間。

也可以使用其他的計算方法:白屏時間 = 頁面開始展示的時間點 - 開始請求的時間點。

TTI

關於 TTI 可以首先了解下谷歌提出的性能模型 RAIL:

RAIL
  1. 響應:輸入延遲時間(從點按到繪制)小於 100 毫秒。用戶點按按鈕(例如打開導航)。
  1. 動畫:每個幀的工作(從 JS 到繪制)完成時間小於 16 毫秒。用戶滾動頁面,拖動手指(例如,打開菜單)或看到動畫。拖動時,應用的響應與手指位置有關(例如,拉動刷新、滑動輪播)。此指標僅適用於拖動的持續階段,不適用於開始階段。
  1. 空閑:主線程 JS 工作分成不大於 50 毫秒的塊。用戶沒有與頁面交互,但主線程應足夠用於處理下一個用戶輸入。
  1. 加載:頁面可以在 1000 毫秒內就緒。用戶加載頁面並看到關鍵路徑內容。

我們可以通過 domContentLoadedEventEnd 來粗略的進行估算:

TTI:domContentLoadedEventEnd - navigationStart

谷歌實驗室也提供了更加便捷准確的 api 包進行測算 tti-polyfil:

import ttiPolyfill from "./path/to/tti-polyfill.js";
ttiPolyfill.getFirstConsistentlyInteractive(opts).then((tti) => {
  // Use `tti` value in some way.
});

LCP

在過去,我們也有推薦的性能指標,如:FMP (First Meaningful Paint)SI (Speed Index)可以幫我們捕獲更多的首次渲染之后的加載性能,但這些過於復雜,而且很難解釋,也經常出錯,沒辦法確定主要內容什么時候加載完。

根據 W3C Web 性能工作組的討論和 Google 的研究,發現度量頁面主要內容的可見時間有一種更精准且簡單的方法是查看 “繪制面積” 最大的元素何時開始渲染。

所謂繪制面積可以理解為每個元素在屏幕上的 “占地面積” ,如果元素延伸到屏幕外,或者元素被裁切了一部分,被裁切的部分不算入在內,只有真正顯示在屏幕里的才算數。圖片元素的面積計算方式稍微有點不同,因為可以通過 CSS 將圖片擴大或縮小顯示,也就是說,圖片有兩個面積:“渲染面積”與“真實面積”。在 LCP 的計算中,圖片的繪制面積將獲取較小的數值。例如:當“渲染面積”小於“真實面積”時,“繪制面積”為“渲染面積”,反之亦然。

頁面在加載過程中,是線性的,元素是一個一個渲染到屏幕上的,而不是一瞬間全渲染到屏幕上,所以“渲染面積”最大的元素隨時在發生變化。如果使用 PerformanceObserver 去捕獲 LCP,會發現每當出現“渲染面積”更大的元素,就會捕獲出一條新的性能條目。

如果元素被刪除,LCP 算法將不再考慮該元素,如果被刪除的元素剛好是 “繪制面積” 最大的元素,則使用新的 “繪制面積” 最大的元素創建一個新的性能條目。

該過程將持續到用戶第一次滾動頁面或第一次用戶輸入(鼠標點擊,鍵盤按鍵等),也就是說,一旦用戶與頁面開始產生交互,則停止報告新的性能條目。

可以直接使用 PerformanceObserver 來捕獲 LCP:

const observer = new PerformanceObserver((entryList) => {
  const entries = entryList.getEntries();
  const lastEntry = entries[entries.length - 1];
  const lcp = lastEntry.renderTime || lastEntry.loadTime;
  console.log("LCP:", lcp);
});
observer.observe({ entryTypes: ["largest-contentful-paint"] });

LCP 也不是完美的,也很容易出錯,它會在用戶進行交互后就停止捕獲,可能會獲取到錯誤的結果,如果有占據頁面很大的輪播圖也會產生問題會不斷的更新 LCP

LCP 也有現成的計算工具庫 web-vitals:

import { getLCP } from "web-vitals";

// Measure and log the current LCP value,
// any time it's ready to be reported.
getLCP(console.log);


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM