INP 三階段完整解析:Input Delay、Processing Time、Presentation Delay 的瀑布圖拆解
INP(Interaction to Next Paint)由 Input Delay、Processing Time、Presentation Delay 三段組成。本文用瀑布圖拆解每段的定義、ms 閾值、獨立測量方式,並提供 DevTools 操作步驟與三個 Before/After 案例,幫你精準定位 INP 瓶頸。
陳柏翰
網站效能工程師
INP 不是一個數字,是一段瀑布圖
INP(Interaction to Next Paint)衡量的是使用者從觸發互動到畫面實際更新的完整延遲。本文專注於解析 INP 的三個組成階段及其獨立測量方式。這段延遲不是一整塊不可分割的時間,而是由 Input Delay、Processing Time、Presentation Delay 三段串接而成。只看最終 INP 數字,你會知道「慢了」,但不知道「卡在哪一段」。把一次互動拆成三段瀑布圖,才能精準定位瓶頸。
這三段的關係是嚴格的時間先後順序:互動觸發後,先經過 Input Delay,再進入 Processing Time,最後才是 Presentation Delay。三段各自獨立測量,加總起來就是該次互動的 INP 值。與 LCP(Largest Contentful Paint)衡量載入速度、CLS(Cumulative Layout Shift)衡量視覺穩定性不同,INP 專注在互動回應性,三者在 Core Web Vitals 中各有明確分工。
舉例來說,一位使用者點擊了購物車的「加入」按鈕。從手指碰到螢幕那一刻起,瀏覽器開始排程事件處理器——這中間可能有其他 long task 佔住主執行緒,產生 Input Delay。事件處理器開始執行後,可能要跑一段同步運算、操作 DOM,這段是 Processing Time。處理器跑完後,瀏覽器還要計算樣式、佈局、繪製、合成,最後像素才真正出現在螢幕上——這就是 Presentation Delay。三段各自可能花不同的時間,瓶頸位置決定你該從哪裡下手優化。
把 INP 拆成三段的意義,在於讓優化方向從「整體降低延遲」變成「針對瓶頸段落精準改動」。這篇文章專注在理解結構,如果你已經知道瓶頸在哪一段、需要具體的優化手法,可以直接參考 INP 優化指南。
Input Delay:從手指碰到畫面到 JavaScript 開始回應
Input Delay 是使用者觸發互動(點擊、按鍵、輕觸)到事件處理器(event handler)開始執行之間的等待時間。這段延遲的主因是主執行緒(main thread)被其他任務佔據——可能是 long task、其他事件處理、或第三方腳本。Input Delay 越長,代表主執行緒的擁塞程度越高。
要偵測 Input Delay,可以透過 Performance Observer API 觀察 event timing 資料。當瀏覽器產生一個 PerformanceEventTiming entry,它的 startTime 與 processingStart 之間的差值就是 Input Delay。搭配 longtask 的 Performance Observer,你可以同時看到是哪個 long task 佔住了 Input Delay 期間。實務上,這讓你能判斷:Input Delay 偏長是自己的程式碼造成的,還是第三方腳本的問題。
Processing Time:事件處理器從執行到完成
Processing Time 是事件處理器開始執行到完成之間的時間。這段時間完全取決於你的 JavaScript 程式碼效率:同步運算量、DOM 操作次數、記憶體配置等。如果 Processing Time 過長,通常代表事件處理器內有 expensive synchronous work 需要拆分或延後執行。
常見的 Processing Time 瓶頸包括:在事件處理器內執行大量同步 DOM 讀寫(例如反覆讀取 offsetHeight)、跑複雜的正則運算或資料處理、在主執行緒上做序列化/反序列化等。如果遇到這類問題,可以考慮將運算拆分到 JavaScript 效能指南 中提到的 Web Worker,或用 debounce / throttle 減少觸發頻率。
Presentation Delay:從處理完成到畫面像素實際更新
Presentation Delay 是事件處理器完成後,到瀏覽器實際將變更渲染到畫面上的時間。這段包含樣式計算(style recalculation)、佈局(layout)、繪製(paint)與合成(composite)。即使 JavaScript 執行很快,如果觸發了大範圍的 reflow 或 complex paint,Presentation Delay 仍然會很長。
瀏覽器的渲染管線依序為:樣式計算 → 佈局 → 繪製 → 合成。每個步驟都可能耗時。樣式計算的時間取決於 CSS 規則的複雜度與受影響元素數量;佈局的時間取決於需要重新計算的 DOM 節點範圍;繪製的時間取決於繪製指令的數量與像素覆蓋面積。如果在 JavaScript 中反覆讀寫佈局屬性(如 offsetWidth、clientHeight),會迫使瀏覽器在每次讀寫之間同步執行佈局,產生所謂的 Layout Thrashing,大幅拉長 Presentation Delay。
要觀察 Presentation Delay,可以在 Chrome DevTools 的 Performance 面板中查看 Event log 的最後一段。Rendering 面板中的 Paint Timing 資料也可以輔助判斷。在 Event Timing API 中,processingEnd 與 presentationTime 之間的差值即為 Presentation Delay。如果這個段落偏長,你需要關注的是 CSS 效率、DOM 節點數量、以及是否有不必要的 reflow 觸發。
三段各自要壓到多少 ms?閾值與判斷方式
點擊事件、按鍵事件、滾動事件的三段比例結構明顯不同。按鍵事件(keydown)的 Processing Time 通常較高,因為要處理輸入邏輯;點擊事件的 Input Delay 可能偏高,因為使用者可能在頁面忙碌時點擊;滾動事件的 Presentation Delay 可能佔主體,因為每次滾動都要重繪可見區域。不建議硬套一個固定比例,而是用 DevTools 量測自己的互動,觀察哪一段佔比最高,再決定優化方向。
判斷瓶頸位置的方法很直接:在 Performance 面板中展開 Event log,看三段各自的 ms 數值。哪段最長、哪段佔比最高,那就是你的瓶頸。搭配 Long Tasks 標記,你可以確認 Input Delay 是否被 long task 佔住;搭配 Call Tree 或 Bottom-Up 視圖,你可以確認 Processing Time 內的時間花在哪個函式呼叫;搭配 Rendering 面板的 Paint Profiler,你可以確認 Presentation Delay 的構成。
用 DevTools 把一次互動的三段瀑布圖挖出來
在 Chrome DevTools 的 Performance 面板中,開啟 Record → 執行互動 → 停止錄製 → 在 Timeline 找到對應的 Event log,展開後可以看到 Interaction to Next Paint 的三段拆分:Input Delay、Processing Time、Presentation Delay 各自的 ms。搭配 Long Tasks 標記,可以同時看到是哪個 long task 佔住了 Input Delay。
具體操作流程如下:第一步,開啟 DevTools → 切換到 Performance 面板 → 點擊左上角的 Record 按鈕開始錄製。第二步,在頁面上執行目標互動——點擊按鈕、按鍵、或滾動。第三步,停止錄製後,在 Timeline 的火焰圖中找到 Interaction to Next Paint 標記。第四步,展開 Event log,你會看到三段各自的 ms 數值,分別對應 Input Delay、Processing Time、Presentation Delay。第五步,展開 Long Tasks 標記,確認是否有 task 佔住 Input Delay 期間。
除了手動操作 DevTools,你也可以用程式化方式偵測。Performance Observer API 提供 event task 與 longtask 兩種 entry type,你可以分別觀察互動事件的 timing 資料與 long task 的佔用時間。web-vitals JS API 封裝了這些底層 API,提供 onINP callback,讓你直接取得每次互動的三段拆分。如果你想深入了解 Performance 面板的進階用法,可以參考 Chrome DevTools Performance 面板指南。
三個案例:同一個按鈕,三段比例完全不同
案例一的瓶頸在 Input Delay。改前 Input Delay 120ms、Processing Time 40ms、Presentation Delay 20ms,整體 INP 180ms。診斷後發現是第三方 analytics 腳本在主執行緒跑了一個 90ms 的 long task,正好卡在互動觸發前。改動方向:將 analytics 腳本移到 idle callback 執行,或用 defer / async 延後載入。改後 Input Delay 降至 30ms,整體 INP 降至 90ms。這類問題的優化路徑對應 INP 優化指南 中的第三方腳本治理策略。
案例二的瓶頸在 Processing Time。改前 Input Delay 30ms、Processing Time 200ms、Presentation Delay 30ms,整體 INP 260ms。事件處理器內有大量同步 DOM 讀寫操作,每次讀寫都觸發瀏覽器重新計算佈局。改動方向:將 DOM 讀寫分批執行,或將複雜運算移到 Web Worker。改後 Processing Time 降至 60ms,整體 INP 降至 130ms。
案例三的瓶頸在 Presentation Delay。改前 Input Delay 20ms、Processing Time 50ms、Presentation Delay 180ms,整體 INP 250ms。互動觸發了一個大範圍的 DOM 更新,瀏覽器需要重新計算 2000 多個節點的佈局並重繪整個可見區域。改動方向:減少單次互動觸發的 DOM 變更範圍,用 content-visibility 或 will-change 降低繪製成本。改後 Presentation Delay 降至 45ms,整體 INP 降至 115ms。三個案例的共同點是:如果不拆成三段,你只會看到 INP 數字偏高,但完全不知道該從哪裡下手。
從三階段到優化路徑:先懂結構,再動手改
理解三階段後,優化路徑自然分岔:Input Delay 偏長 → 看 long task 和第三方腳本;Processing Time 偏長 → 看 debounce / throttle 和 Worker 移運算;Presentation Delay 偏長 → 看 Layout Thrashing 和 paint 範圍。每個瓶頸段落對應不同的優化手法,這就是為什麼先把結構搞清楚,比直接跳進優化技巧更重要。
本站的 INP 學習路徑從這篇概念入口開始,沿著不同瓶頸方向延伸到專題頁面:Input Delay 相關的 long task 與第三方腳本問題、Processing Time 相關的 debounce / throttle 技巧、Web Worker 移運算策略、以及 React hydration 的特殊場景。這篇文章提供判斷框架,讓你知道自己該往哪個方向深入。
在實務操作上,建議的閱讀順序是:先用這篇文章建立三階段的認知框架 → 用 DevTools 量測自己的網站,確認瓶頸段落 → 進入對應的優化指南處理具體問題。除了 DevTools,Web Vitals Chrome Extension 也提供即時的 INP 觀測,讓你快速確認改動前後的數字變化。記住,INP 是一個動態指標——不同互動類型、不同使用情境下的三段比例可能完全不同,持續量測比一次性優化更重要。
INP 的三段分別是什麼?
INP 由 Input Delay、Processing Time、Presentation Delay 三段組成。Input Delay 是互動觸發到事件處理器開始執行之間的等待時間,主因是主執行緒被其他任務佔據。Processing Time 是事件處理器從開始執行到完成之間的時間,取決於 JavaScript 程式碼效率。Presentation Delay 是處理器完成後到畫面像素實際更新之間的時間,包含樣式計算、佈局、繪製與合成。
怎麼知道我的 INP 瓶頸在哪一段?
用 Chrome DevTools 的 Performance 面板錄製一次互動,在 Timeline 中找到 Interaction to Next Paint 標記並展開 Event log,可以看到三段各自的 ms 數值。哪段最長、佔比最高,就是你的瓶頸。搭配 Long Tasks 標記可以確認 Input Delay 是否被 long task 佔住。
Input Delay 偏長通常代表什麼問題?
Input Delay 偏長代表主執行緒在互動觸發時正被其他任務佔據。常見原因包括第三方腳本(如 analytics、A/B 測試工具)在主執行緒跑長時間運算、其他 long task 排在前面、或先前的互動事件處理器還沒執行完。改善方向是減少 long task 的數量與長度,或將第三方腳本移到非關鍵路徑。
INP 的整體閾值是多少?
根據 Core Web Vitals,INP 的整體良好閾值是 200 毫秒或更低。但重要的是,INP 由三段組成,每段都可以獨立優化,因此應專注於識別瓶頸段落而非單一數字。
Presentation Delay 偏長可以怎麼改善?
Presentation Delay 涵蓋樣式計算、佈局、繪製與合成。偏長通常代表觸發了大範圍的 reflow 或 complex paint。改善方向包括:減少單次互動觸發的 DOM 變更範圍、避免 Layout Thrashing(不要在迴圈中反覆讀寫佈局屬性)、用 content-visibility 降低繪製範圍、減少 CSS 規則複雜度與受影響元素數量。
三階段拆分和整體 INP 數字的關係是什麼?
三段嚴格按照時間先後順序串接:Input Delay + Processing Time + Presentation Delay = 該次互動的 INP 值。每段都可以獨立測量,用 Performance Observer API 的 event timing entry 中的 startTime、processingStart、processingEnd、presentationTime 來計算。拆分的意義在於讓優化方向從「整體降低延遲」變成「針對瓶頸段落精準改動」。