具代表性的面試主題

前端面試:如何診斷 Long Task 並改善 INP?

前端困難
OfferCC 編輯團隊發佈 更新

題幹

使用者反映點擊篩選按鈕後頁面卡頓。請說明如何定位主執行緒 Long Task,如何判斷它對 INP 的影響,並給出修復與驗證方案。

題幹與適用場景

使用者反映點擊篩選按鈕後頁面卡頓。請說明如何定位主執行緒 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 反映互動到下一次繪製的回應。

公開來源

同類題目