1. 題目與適用場景
這題面向前端效能與瀏覽器基礎面試。頁面同時有使用者輸入、捲動和動畫,也需要處理分析事件、低優先級計算或延後工作。候選人要說明閒置回呼解決什麼問題、如何避免無限等待,以及為什麼 DOM 提交通常應交給 requestAnimationFrame。
2. 面試官考察點
- 是否理解
requestIdleCallback是瀏覽器在閒置時排程低優先級工作,不是搶占執行緒。 - 是否會用
IdleDeadline.timeRemaining()分塊,並為有截止要求的工作設定timeout。 - 是否知道此 API 的瀏覽器支援有限,能設計能力偵測和語義清楚的降級。
- 是否能區分計算、網路傳送、DOM 變更與動畫時機,並用真實互動指標驗證收益。
Coursera 的前端面試指南把效能最佳化、生產指標和權衡列為核心考察內容。MDN 說明 requestIdleCallback() 用於閒置期間的背景工作,timeout 可避免必要工作等待過久,但會帶來互動風險;Chrome 官方範例進一步區分閒置計算與下一幀的 DOM 更新。
3. 回答前需要釐清的問題
- 工作是否可以延遲?分析批次、預取和必要的使用者回饋,各自的截止時間是什麼?
- 回呼結果會修改 DOM、更新狀態、寫入儲存,還是只傳送網路請求?
- 目標瀏覽器是否支援此 API?不支援時,延後、立即執行或捨棄工作的語義是什麼?
- 要保護的指標是輸入延遲、長任務、動畫流暢度,還是分析資料送達率?
4. 30 秒回答框架
我會先把工作分為可捨棄、可延後和必須完成三類。對小塊的非關鍵計算或傳送佇列,用 requestIdleCallback 在 timeRemaining() 允許的範圍處理,並為有時限的任務設定 timeout。回呼不直接做不可預測的 DOM 變更;它準備的資料交給下一次 requestAnimationFrame 提交。先偵測能力,降級路徑保持取消、過期和送達語義,再用輸入延遲、長任務和業務完成率驗證結果。
5. 分步深入解答
第一步:先判斷工作是否適合閒置時段
使用者輸入回饋、動畫和首屏關鍵渲染不能依賴閒置時機。分析事件批次、非關鍵預取、索引切片和背景序列化更適合延後。必須在截止時間前完成的工作需要 timeout,但逾時後可能爭用互動資源,應重新評估工作量或拆分任務。
第二步:依時間預算分塊並保持可重入
回呼會收到 deadline,每次只處理能在 timeRemaining() 內完成的小批次;仍有工作就重新排隊。佇列要有去重標記,避免每次事件都註冊一個回呼。路由切換、元件卸載或新版本結果出現時,應清理待處理任務,避免過期結果寫回頁面。
第三步:區分計算、網路與 DOM 時機
閒置回呼適合準備資料、序列化或排隊傳送;網路請求本身不保證回呼持續擁有閒置預算。DOM 寫入可能觸發版面配置和繪製,時間不可預測,應先在閒置階段建立結果,再於 requestAnimationFrame 集中提交。若計算本身很重,使用 Worker 隔離主執行緒比持續切片更可靠。
第四步:設計相容性與驗證閉環
用能力偵測決定原生排程、計時器或訊息通道降級。降級實作不要宣稱擁有原生閒置語義;明確它是延後執行、盡快執行還是放棄。記錄佇列長度、等待時間、逾時次數、取消命中率、輸入延遲和長任務,再比較啟用前後的真實使用者資料。
6. 高品質示範回答
我會先問這項工作是否影響目前互動,以及最晚何時必須完成。分析事件、非關鍵預取和可切片的序列化可以進入 requestIdleCallback;使用者輸入回饋、動畫和首屏關鍵路徑不能等待閒置。
實作時我會在回呼中循環處理小批次,直到 timeRemaining() 不足;有業務截止時間的佇列才設定 timeout,並接受逾時可能造成卡頓的代價。回呼只準備資料,DOM 更新交給下一次 requestAnimationFrame。元件卸載或結果版本變化時取消佇列,防止舊結果寫回。
由於 MDN 標示此 API 的支援範圍有限,我會先做能力偵測。沒有原生支援時,依業務選擇計時器或訊息通道延後,或直接捨棄可選工作,並保持相同的過期規則。最後用輸入延遲、長任務、佇列等待、逾時次數和分析送達率驗證是否真的改善使用者體驗。
7. 常見錯誤
- 把閒置回呼當成背景執行緒;它仍在主執行緒執行,長同步程式仍會阻塞輸入。
- 無條件設定很短的
timeout;逾時會把低優先級工作變成突發的互動競爭。 - 在閒置回呼直接大量改 DOM;不可預測的版面和繪製可能抵銷收益。
- 不做能力偵測,把支援有限的 API 當成業務正確性的前提。
- 每個事件都排隊一次,忽略合併、去重、取消和結果版本。
8. 追問及應對
追問一:沒有閒置時間時,回呼會永遠不執行嗎?
沒有 timeout 時,必要工作確實可能等待很久。對有截止要求的工作設定 timeout,並在逾時路徑減少批量或改用更直接的排程;對可捨棄工作則允許過期,不應為了完成它犧牲輸入回應。
追問二:為什麼不在 requestIdleCallback 直接更新 DOM?
DOM 變更的版面、繪製和合成成本不穩定,可能超過閒置預算。可以在閒置階段計算或建立文件片段,再在 requestAnimationFrame 提交可見變化,並用長任務和輸入延遲驗證。
追問三:什麼時候應該使用 Worker?
當任務是持續的 CPU 密集計算,且切片後仍佔用主執行緒,Worker 能隔離計算。它增加序列化、通訊和取消設計成本;小型、可延後的工作則優先用閒置回呼保持方案簡單。