如果互動回應不佳,使用者會覺得網頁速度緩慢,甚至完全無法運作。Interaction to Next Paint (INP) 是以 Event Timing API 為基礎的指標。這項指標會評估最差的互動 (不計部分離群值),做為網頁回應速度的衡量標準。
找出網頁沒有回應的根本原因可能很棘手,尤其是因為這取決於使用者互動和環境條件,例如裝置功能和網路條件。相較於載入網頁等可重複且可預測的情境,這類問題更難診斷。實驗室資料只會複製一小部分實際使用者情境,因此必須評估實際環境中 INP 緩慢的原因。
Event Timing API 可將 INP 時間長度分為三個子部分:輸入延遲 (互動發生時已在進行的處理作業)、處理時間長度 (互動直接造成的延遲),以及顯示延遲 (互動後轉譯下一個影格造成的延遲)。這有助於判斷問題是出在其他程式碼、互動 JavaScript 程式碼,還是瀏覽器處理轉譯更新,而不是直接跳到互動程式碼。
您可以進一步瞭解 JavaScript、樣式重新計算和版面配置工作延遲互動的情形。使用 JS Self-Profiling API 進行完整效能追蹤,是相當耗費資源的解決方案,容易造成效能問題。Long Animation Frames API 是一種輕量 API,可用於實際環境,在 INP 互動期間識別執行速度緩慢的 JavaScript,並區分樣式重新計算和版面配置成本:
- 指令碼層級強制樣式和版面配置 (
forcedStyleDuration和forcedLayoutDuration):在輸入延遲或處理時間期間,回報執行中指令碼內的同步樣式重新計算 (例如在 DOM 變異後呼叫getComputedStyle()) 和強制版面配置/重排 (例如在變異後讀取getBoundingClientRect()或offsetWidth)。 - 影格層級算繪樣式和版面配置 (
styleDuration和layoutDuration):回報在影格算繪更新期間,重新計算樣式與更新版面配置所花費的時間,有助於解釋呈現延遲過高的原因。
區分樣式重新計算和版面配置至關重要,因為兩者的根本原因和修正方式不同:樣式持續時間過長,代表 CSS 選取器比對成本高昂,或樣式失效範圍過廣 (可透過簡化選取器或縮減規則範圍來修正);版面配置持續時間過長,則代表幾何圖形計算成本高昂,或同步版面配置頻繁變動 (可透過在寫入前批次處理 DOM 讀取、簡化 DOM 結構或使用 CSS 限制來修正)。
導入方式
從原始 Event Timing API 計算 INP 相當複雜,且有幾項細微差異。建議您使用 RUM 工具或程式庫收集這項資料。
web-vitals 是 Google 的開放原始碼程式庫,可計算 Core Web Vitals (包括 INP),也包含 INP 互動的子部分和長動畫影格資料。
使用 web-vitals 程式庫取得 INP 互動的歸因
web-vitals 程式庫是小型程式庫,用於評估 Core Web Vitals 和其他成效指標。onINP() 函式可用來找出最慢的互動,並包含 INP 子部分、互動期間執行的指令碼,以及使用 Long Animation Frames API 的樣式和版面配置持續時間等資訊。
// Use the attribution build to get Long Animation Frame data
// alongside the INP metric value.
import { onINP } from 'web-vitals/attribution';
onINP((metric) => {
const { attribution } = metric;
const longestScript = attribution.longestScript;
// Sum rendering-phase style and layout durations across all LoAF entries
// intersecting the INP interaction (primarily explains presentationDelay).
let renderStyleDuration = 0;
let renderLayoutDuration = 0;
for (const entry of attribution.longAnimationFrameEntries) {
renderStyleDuration += entry.styleDuration ?? 0;
renderLayoutDuration += entry.layoutDuration ?? 0;
}
// Beacon script, style, and layout attribution for the INP interaction,
// so you can identify the root cause in production.
navigator.sendBeacon(
'/analytics',
JSON.stringify({
name: 'INP',
value: metric.value,
// These fields give the INP subparts:
inputDelay: attribution.inputDelay,
presentationDelay: attribution.presentationDelay,
processingDuration: attribution.processingDuration,
interactionTarget: attribution.interactionTarget,
// These fields identify which script function was responsible
// for the longest processing during the INP interaction.
invokerType: longestScript?.entry?.invokerType,
sourceURL: longestScript?.entry?.sourceURL,
sourceFunctionName: longestScript?.entry?.sourceFunctionName,
sourceCharPosition: longestScript?.entry?.sourceCharPosition,
// subpart indicates which phase (input delay, processing, or
// presentation delay) the longest script overlapped with most.
subpart: longestScript?.subpart,
intersectingDuration: longestScript?.intersectingDuration,
// Synchronous style and layout work forced inside the longest script
// (with forcedStyleAndLayoutDuration as a combined fallback):
forcedStyleDuration: longestScript?.entry?.forcedStyleDuration,
forcedLayoutDuration: longestScript?.entry?.forcedLayoutDuration,
forcedStyleAndLayoutDuration: longestScript?.entry?.forcedStyleAndLayoutDuration,
// Rendering-phase style and layout work across the interaction's frames
// (with totalStyleAndLayoutDuration as a combined fallback):
renderStyleDuration,
renderLayoutDuration,
totalStyleAndLayoutDuration: attribution.totalStyleAndLayoutDuration
})
);
});
最佳做法
- 建議先使用 INP 子部分,判斷延遲是否已執行 JavaScript (輸入延遲)、互動的事件處理常式 JavaScript (處理時間),或後續算繪 (呈現延遲)。
- 建議嘗試找出造成最大阻礙的 JavaScript,並提供額外詳細資料,特別是輸入延遲和處理時間。
- 務必區分樣式重新計算 (
styleDuration、forcedStyleDuration) 和版面配置 (layoutDuration、forcedLayoutDuration),以便診斷處理時間過長或顯示延遲問題:樣式時間過長表示 CSS 選取器耗費大量資源或無效範圍過廣,而版面配置時間過長則表示 DOM 幾何圖形瓶頸或同步版面配置抖動。 - 建議使用 Long Animation Frames API 提供這類詳細資料,而非 JS Self-Profiling API 等替代方案,因為後者會產生較高的執行階段負擔。
- 如果沒有其他 RUM 解決方案,請使用
web-vitals程式庫。這項工具可識別 INP 互動,並提供互動期間執行的子部分和指令碼相關資訊 (使用 Long Animation Frames API)。 - 務必將必要資訊傳回數據分析服務,而非僅記錄在本機。
瀏覽器支援和備用策略
Event Timing API 適用於大多數新式瀏覽器,是計算 INP 和 INP 子部分所必需。如果瀏覽器不支援這個 API,就無法評估 INP。
Long Animation Frames API 提供選用的額外詳細資料。您可以放心使用,不必擔心備用方案。在大多數情況下,它找出的效能提升機會也適用於其他瀏覽器。
如果 Baseline 目標支援 長動畫影格 API (long-animation-frames),但不支援獨立的樣式和版面配置時間長度屬性 (PerformanceLongAnimationFrameTiming 上的 styleDuration 和 layoutDuration,或 PerformanceScriptTiming 上的 forcedStyleDuration 和 forcedLayoutDuration),請改用合併的樣式和版面配置時間:
- 在
PerformanceScriptTiming上使用script.forcedStyleAndLayoutDuration,在指令碼中同步強制執行樣式和版面配置工作。 - 在
web-vitals/attribution中使用metric.attribution.totalStyleAndLayoutDuration(或在每個PerformanceLongAnimationFrameTiming項目上計算(entry.paintTime || entry.startTime + entry.duration) - entry.styleAndLayoutStart),以結合樣式和版面配置。