murattunalı.

What INP is and how to measure it.

INP is the time from a user interaction until the page responds visually, and Google counts under 200 milliseconds as good.

This is the metric that entered Core Web Vitals in March 2024 and replaced FID. The change mattered because FID measured only the DELAY of the FIRST interaction — the time from the user’s click until the browser began processing. Whether the click’s result ever reached the screen was never measured.

The practical consequence: a page could respond quickly to the first click and freeze on every later interaction, and FID would still come out perfect. INP looks at interactions across the whole session and measures not the delay but the full cycle. A much harder and much more honest exam.

Three phases

An interaction’s duration splits into three parts, and diagnosis requires separating them.

  1. Input delay — the user clicked, but the main thread is busy with other work. The time until the handler starts running.
  2. Processing time — how long did the event handlers themselves take? Your code’s direct responsibility.
  3. Presentation delay — the handler finished, but when could the browser get to painting the next frame?

Most teams think only of the second phase and optimize the event handlers. Yet in field data the largest share usually goes to the first and third phases — the problem is not that your handler is slow, but that the main thread is busy with something else.

The most practical consequence of this distinction: most INP problems live somewhere unrelated to the interaction — in long scripts running during page load, in third-party code, or in a heavy framework’s hydration work.

The main thread

In the browser, JavaScript runs on a single thread, and that thread is also responsible for layout and painting. While a long JavaScript task runs, the browser can paint nothing and answer no click — the page looks frozen.

The most effective INP treatment is therefore splitting long tasks. Every task longer than fifty milliseconds leaves the page unresponsive for that duration. Splitting the work into small pieces and yielding control back to the browser between them does not change the total time — but it keeps the page usable.

The second treatment is moving the work off the main thread entirely. Heavy computations can move to background threads; code running there never blocks the user interface. Not possible for every job, but the cleanest solution for computation-heavy work.

The third and highest-yield: not doing the needless work at all. Loading and running an unused library costs more than the best splitting strategy can save. The first step of INP work is not optimization but inventory.

The fastest JavaScript is the JavaScript that never runs.

Why it cannot be measured in the lab

INP’s most vexing trait is that lab tools cannot measure it reliably. The reason is in its definition: the metric looks at real user interactions, and an audit tool does not interact with the page. Tools can produce an estimate, but that estimate does not represent real use.

For INP, field data is therefore not an option but a necessity. The browser collects the values real users experience, and this data becomes reachable both in Google’s own reports and through a small measurement snippet you add to your own page.

The advantage of running your own measurement is detail: you can see which interaction was slow, on which page and on which element. Google’s aggregate report gives you a number; your own measurement says where that number comes from.

A privacy note: this measurement needs no cookies and collects no personal data — only duration values and the selector of the interacted element are recorded. On this site the privacy text says no cookies are used, and the suite measures that on every run; no added measurement may break that claim.

Where to start

Unlike the other two metrics, INP work starts with an inventory. The source of the problem is usually not the interaction code you wrote but the total of the work running on the page — so that total must be seen first.

  1. List the loaded scripts — how many files, how many bytes, which are third-party?
  2. Find the long tasks — the performance panel marks tasks over fifty milliseconds; which file is the source?
  3. Weigh the third parties — the chat bubble, the analytics, the ads. Each one’s cost to the main thread can be measured separately.
  4. Ask what is truly needed — which library serves which feature? Remove the unused ones.
  5. Defer the rest — work that needs no interaction can move past the first paint.
  6. Split the long tasks — move the unsplittable ones to a background thread.

This order puts the biggest win on top: a script that never loads costs zero, and no optimization can match that result. On this site the vendor libraries are 55.7 kilobytes after gzip and the list holds only the five modules actually in use — the concrete counterpart of inventory discipline.

One measurement note: INP is reported in field data at the 75th percentile — the time three quarters of users experience. The value you measure on your own powerful device is at the best end of that distribution and does not represent real user experience. Testing on a low-powered device is more critical for INP than for the other two metrics.

The price of the framework choice

The single decision with the largest effect on INP is usually one never taken as a performance decision at all: which frontend framework to use. Pages generated on the server and rehydrated on the client keep the main thread busy for the duration of that hydration, and every click made in that window is delayed.

This does not make frameworks bad — complex applications may need them. But for a brochure site, a blog or a portfolio, paying that cost rarely has a return. On this site there is no client-side hydration; pages arrive as files, and JavaScript builds only the motion layer.

The measured result: own code 28 kilobytes after gzip, vendor libraries 55.7 kilobytes. A total of 83.7 kilobytes, well under the 150-kilobyte budget ceiling. That figure is not an optimization achievement but the natural consequence of an architectural decision.

SOURCES