題幹與適用場景
使用者反映點擊篩選按鈕後頁面卡頓。請說明如何定位主執行緒 Long Task,如何判斷它對 Interaction to Next Paint(INP)的影響,並給出修復與驗證方案。
回答應區分輸入延遲、事件處理耗時和下一次繪製延遲;不能只說「做防抖」或「上 Web Worker」。需要涵蓋真實使用者資料、實驗室診斷、回歸指標和降級邊界。
面試官考察點
效能模型
強回答能把一次互動拆成輸入等待、事件處理、渲染與繪製,並解釋主執行緒被長任務佔用時瀏覽器無法及時回應。
證據定位
候選人應結合 PerformanceObserver、瀏覽器 Performance 面板和互動上下文定位腳本、元件和資料規模,而不是憑感覺猜測。
修復取捨
要說明拆分任務、減少同步工作、虛擬化、延遲非關鍵更新和 Worker 的適用條件,同時考慮序列化成本與狀態一致性。
真實驗證
回答應同時看 p75 INP、長任務數、互動分位數和業務轉化,區分實驗室樣本與真實裝置、網路和低端 CPU。
回答前需要釐清的問題
- 卡頓發生在所有互動還是特定篩選條件?
- 目標裝置、瀏覽器和資料量是什麼?
- 問題是首次載入、互動處理,還是繪製後的佈局?
- 是否有真實使用者 INP、事件時長和長任務資料?
- 篩選結果需要同步更新,還是可以先回應再漸進計算?
- 業務是否允許改變排序、分頁或結果精度?
30 秒回答框架
「我先用真實使用者 INP 和互動事件定位受影響頁面,再在同一裝置和資料量下錄製 Performance trace。PerformanceObserver 監測 50ms 以上的 longtask,面板用於定位腳本呼叫堆疊和繪製階段。若事件處理同步計算過重,我會先拆分工作、減少重複渲染和虛擬化列表;可並行的純計算再評估 Worker,但會計入序列化和排程成本。修復後用 p75 INP、互動長任務和轉化率做前後對照。」
分步驟深入解答
第一步:建立基線
按頁面、互動類型、裝置和版本記錄 p75 INP、事件處理時長、下一次繪製延遲、長任務數和錯誤率。不要用單次本地快機結果代表全體使用者。
第二步:複現與定位
使用瀏覽器 Performance 面板錄製真實篩選操作,查看主執行緒火焰圖、Long Tasks、佈局和繪製。PerformanceObserver 可在執行時收集 longtask 記錄,再把頁面、互動和版本資訊關聯到樣本。
第三步:區分瓶頸
若輸入等待長,檢查前一個同步任務;若事件處理長,檢查解析、過濾和狀態更新;若繪製長,檢查佈局、樣式和大 DOM。INP 關注一次互動從輸入到下一次繪製的完整回應,不等同於單個函式耗時。
第四步:降低同步工作
先減少計算量和重複渲染,使用分頁、虛擬化、增量過濾和快取。把非關鍵日誌、預取和分析移出關鍵互動路徑;必要時用 requestIdleCallback 或分片排程,但要處理閒置時間不足。
第五步:評估 Worker
純 CPU 計算且資料可複製時可用 Worker;大物件複製、頻繁訊息和 DOM 存取會抵消收益。保持 UI 狀態與結果版本一致,取消過時任務,避免舊結果覆蓋新篩選。
第六步:驗證與防回歸
在代表性低端裝置和資料集重複錄製,並做灰度發布。比較 p75/p95 INP、longtask 數、互動成功率、取消率和轉化;建立預算,超過閾值時阻斷回歸或觸發告警。
高品質示範回答
「我先從真實使用者資料確認問題集中在哪個互動、裝置和版本,再用相同資料量錄製篩選操作。火焰圖顯示事件處理同時做了大陣列過濾、狀態更新和列表佈局,因此我會先快取過濾結果、虛擬化列表,並把非關鍵更新延後。
我用 PerformanceObserver 記錄 50ms 以上 longtask,並把樣本關聯到頁面和互動;如果過濾仍是純 CPU 瓶頸,再把它移到 Worker,同時限制訊息大小和丟棄過時結果。修復在低端裝置灰度,比較 p75 INP、長任務數、取消率和篩選完成率,確認真實使用者改善後再擴大範圍。」
常見錯誤
- 只看平均回應時間 → 尾部使用者被掩蓋 → 看 p75/p95 INP 和裝置分層。
- 把 Long Task 等同於 INP → 忽略輸入和繪製階段 → 追蹤一次互動的完整時間線。
- 看到卡頓就加防抖 → 可能延遲必要回饋 → 先定位計算、渲染或網路瓶頸。
- 所有計算都丟給 Worker → 複製和訊息成本增加 → 只遷移純 CPU 且收益明確的工作。
- 只在開發機驗證 → 低端裝置仍卡頓 → 用代表性裝置、資料和灰度樣本複測。
- 分片排程不設取消 → 過時結果覆蓋新狀態 → 為任務加版本、取消和提交檢查。
- 只做實驗室 Lighthouse → 無法反映真實互動 → 接入真實使用者 INP 與長任務採樣。
- 修復後沒有效能預算 → 回歸無法被發現 → 為關鍵互動設閾值和持續監控。
追問及應對
追問一:Long Task 只有 60ms,為什麼 INP 仍很差?
檢查互動前的輸入等待、事件處理後的佈局與繪製,以及多個相鄰任務;INP 是完整回應路徑,單個 60ms 不是全部解釋。
追問二:Worker 讓結果更慢怎麼辦?
測量序列化、傳輸和排程成本;對小資料保留主執行緒快路徑,對大資料批量傳送或使用可轉移物件,並取消過時請求。
追問三:如何觀測 longtask 的來源?
在 PerformanceObserver 記錄 startTime、duration、頁面和版本,並結合 Performance trace 的呼叫堆疊;不要把使用者資料中的敏感輸入寫入日誌。
追問四:篩選結果必須即時怎麼辦?
先同步確認輸入並顯示載入狀態,再增量計算結果;保持結果版本與篩選條件一致,必要時顯示暫態結果和完成狀態。
追問五:如何證明修復沒有傷害轉化?
灰度比較 p75 INP、互動完成率、取消率、錯誤率和核心轉化,按裝置和網路分層,並設定停止條件。
來源一:MDN Performance data
MDN 說明 longtask 記錄代表持續 50ms 或更久的任務,可作為主執行緒阻塞的執行時證據。
來源二:PerformanceObserver
MDN 的 PerformanceObserver 文件說明如何觀察效能條目,為採集 longtask 和關聯頁面版本提供 API 依據。
來源三:web.dev Long Tasks 與 INP
web.dev 解釋長任務會阻塞主執行緒、延遲使用者回饋,並建議拆分任務、減少同步工作和評估 Worker;INP 反映互動到下一次繪製的回應。