前端面試:如何用 Long Animation Frames API 定位現場 INP 問題?
題幹與適用場景
頁面在 Lighthouse 中表現良好,真實使用者卻回報點擊後介面卡頓。團隊已有基礎 RUM,但只上報 INP 數值,無法回答是事件處理器、requestAnimationFrame、樣式布局還是第三方腳本造成延遲。請設計 LoAF 觀測、關聯、取樣、聚合和修復閉環。
面試官考察點
- 是否理解 INP 的輸入延遲、處理時間和展示延遲。
- 是否知道 LoAF 以超過 50 毫秒的幀為單位,並提供腳本歸因與渲染時間。
- 是否能將互動、LoAF、頁面版本和裝置上下文關聯,而不是上傳所有原始事件。
- 是否處理瀏覽器支援差異、緩衝區、跨來源腳本和隱私風險。
- 是否提出從資料到程式碼修復、回歸驗證和告警的閉環。
回答前需要釐清的問題
- 目標是診斷 INP,還是同時關注動畫流暢度和長任務?
- 取樣比例、日活、事件上報預算和資料保留期是多少?
- 是否允許記錄 URL、腳本來源、使用者操作類型和頁面版本?
- 需要支援哪些瀏覽器,不支援 LoAF 的客戶端如何降級?
- 哪些團隊負責接收告警並驗證修復,閾值按 p75、p95 還是裝置分層?
30 秒回答框架
「我會把 INP 的階段分解與 LoAF 觀測放在同一條 RUM 關聯鏈路中。用 PerformanceObserver 監聽 long-animation-frame,只保留與高 INP 互動時間窗相交的幀,並記錄 duration、blockingDuration、renderStart、styleAndLayoutStart 和腳本歸因。客戶端先做能力偵測、去識別化和動態取樣,再批次上報頁面版本、裝置分層與匿名工作階段鍵。伺服器按互動類型和版本聚合,告警連到 sourceURL 與函式,修復後用相同分層驗證回歸。」
分步驟深入解答
1. 先拆解 INP 階段
輸入延遲是事件排隊到處理開始的時間,處理時間是事件回呼執行時間,展示延遲是處理結束到下一幀呈現的時間。LoAF 不能取代 INP,它提供幀級上下文,幫助判斷慢點落在哪個階段。
2. 觀測 LoAF 條目
用 PerformanceObserver 觀察 long-animation-frame,而不是反覆讀取效能時間線。LoAF 的閾值是 50 毫秒,條目含 duration、blockingDuration、renderStart、styleAndLayoutStart、firstUIEventTimestamp 和 scripts 等欄位。
if (PerformanceObserver.supportedEntryTypes.includes("long-animation-frame")) {
const observer = new PerformanceObserver((list) => {
for (const entry of list.getEntries()) {
queueFrameForCorrelation(entry);
}
});
observer.observe({ type: "long-animation-frame", buffered: true });
}3. 關聯互動與頁面版本
保存最近一段時間的 INP 互動摘要和 LoAF 環形緩衝。互動結束時,用 firstUIEventTimestamp、startTime 和 duration 判斷相交幀,只關聯最有解釋力的少量條目。每個摘要帶頁面版本、實驗分組、裝置類別和匿名工作階段鍵,避免上傳完整輸入內容。
4. 解釋腳本與渲染開銷
blockingDuration 反映會阻塞輸入或高優先級任務的時間;renderStart 和 styleAndLayoutStart 可估算渲染前、樣式布局與其餘階段。scripts 可指出主執行緒腳本的 URL、函式和呼叫者類型,但跨來源 iframe、Worker 和擴充功能腳本可能沒有完整歸因。
5. 設計取樣與隱私保護
預設只上報高 INP、長幀異常或低比例隨機樣本;為同一匿名工作階段設定速率上限。腳本 URL 做網域白名單或雜湊,移除查詢參數、使用者輸入和 DOM 文字;敏感頁面關閉詳細歸因。伺服器設定保留期、存取控制和刪除機制,並記錄取樣規則版本。
6. 建立聚合與修復閉環
按互動類型、頁面版本、裝置、網路和腳本來源聚合 p75/p95,而不是只看全站平均值。告警同時展示輸入、處理、展示階段和最常見歸因。修復前後使用相同取樣與分層比較,確認新版本沒有把問題轉移到另一類裝置或互動。
高品質示範回答
「我會先用 INP 階段分解確定是輸入、處理還是展示延遲,再用 LoAF 補充幀級證據。客戶端透過能力偵測觀察 long-animation-frame,只保存與高 INP 互動相交的條目,帶上 duration、blockingDuration、渲染時間和可用的腳本歸因。關聯鍵是頁面版本、實驗分組、裝置分層和匿名工作階段,而不是使用者輸入。詳細歸因採用動態取樣,URL 去識別化並限制保留期;不支援 LoAF 的瀏覽器仍上報基礎 INP。伺服器按互動、版本和裝置聚合,告警指向程式碼來源,修復後做分層回歸驗證。」
常見錯誤
- 只上報 INP 一個數字 → 無法定位階段和程式碼 → 關聯 INP 階段與 LoAF 幀。
- 把每個長幀原樣上傳 → 成本高且暴露腳本與使用者上下文 → 按高 INP 相交、取樣和去識別化上報。
- 把 50 毫秒當成 INP 合格線 → LoAF 閾值與 INP 目標混淆 → 分別解釋幀閾值和業務指標分位數。
- 假設所有腳本都有歸因 → 跨來源 iframe、Worker 等資料不完整 → 標記歸因缺失並結合版本與裝置分析。
- 只看全站平均值 → 少數裝置的嚴重問題被掩蓋 → 按互動、裝置、網路和版本分層。
追問及應對
LoAF 會取代 Long Tasks API 嗎?
不會直接取代。LoAF 以幀為單位並提供更完整上下文,Long Tasks 仍可用於既有監控和相容瀏覽器。遷移時應並行比較資料,而不是突然刪除舊指標。
為什麼不能上傳所有腳本 URL?
URL 可能包含使用者識別、查詢參數或內部路徑,也會放大資料量。應移除參數、限制網域、雜湊或只保留版本化來源映射,並依頁面敏感度調整詳細度。
如何判斷是樣式布局而不是腳本執行?
比較 renderStart、styleAndLayoutStart、duration 和腳本條目。如果腳本時間不高但樣式布局區間很長,優先檢查 DOM 規模、選擇器和同步布局;仍需用實驗室 trace 重現確認。
不支援 LoAF 的瀏覽器怎麼辦?
能力偵測後降級到基礎 INP、Event Timing 或 Long Tasks 資料,並在伺服器標記觀測版本。不要把缺失 LoAF 的使用者排除出整體體驗指標,要在分層報告中說明診斷能力差異。