Skip to content
Workshop tools
All tools

INP stress test

Slow a page down on purpose, watch the three parts of every interaction from your own browser's timing data, and try the strategies that fix it.

Runs in your browser. Nothing is uploaded.

Tool

Nothing heavy runs until you change a setting and then interact. The defaults are light. The heavy settings block the main thread on purpose, so the page may feel frozen; the Stop and Reset controls and the Escape key are there to turn the load off.

Loading the stress test. It needs JavaScript.

What the numbers mean

Every interaction has three parts: input delay (the time before any callback is handled), processing time (the time for all the callbacks to run), and presentation delay (the time from the end of the callbacks until the next frame is shown). The browser reports them through Event Timing: processingStart minus startTime, processingEnd minus processingStart, and the rest of the duration.

INP at or below 200 ms is good, above 200 ms and up to 500 ms needs improvement, and above 500 ms is poor, measured at the 75th percentile of page loads in the field. On this page the figure is the worst interaction you recorded, ignoring one highest interaction for every 50, which is how web.dev describes the metric. It is an approximation from your own interactions only.

The five strategies

sync
All the work runs inside the event handler. The browser cannot paint until the handler returns, so the whole cost lands in the interaction.
yield
The work is cut into 50 ms chunks with a yield to the main thread between them (scheduler.yield(), or setTimeout where it is missing), so the browser can paint and handle input in the gaps.
idle
Non-urgent work is queued with requestIdleCallback and run only in the time the browser reports as idle, in small slices. Good for work nobody is waiting for; it can finish late.
worker
The pure computation (counting primes for the chosen time) runs in a Web Worker, off the main thread. Only the result comes back, so the main thread stays free. Work that touches the DOM cannot move there.
defer-render
A small visible update is made first and painted, then the remaining work and the large list render afterwards. The total work is unchanged; the user sees a response sooner.

Try it

  1. Set Handler work to 500 ms and keep the strategy on sync. Press Add to cart. The total and processing time jump.
  2. Switch to yield, press it again, and compare the two rows in the comparison table at the same workload.
  3. Raise DOM size to 10,000 and press Re-render list to see presentation delay grow, then try defer-render.
  4. Turn on the noisy neighbour and watch input delay appear on interactions that did nothing wrong.

Text equivalent: the controls on the left set how much work each interaction does; the target holds a button, a text field and a list that run that work; the results list the three phases of each interaction, mark the worst one with the word Worst, and compare strategies. Everything works from the keyboard.

What this can't check
  • It does not report real-user data and never sends anything anywhere. The figure it shows is not your site's INP and is never called that.
  • Event Timing only reports interactions of 16 ms or more, rounds durations to 8 ms, and is not available in every browser.
  • The figure covers only the interactions you make on this page, on this device, in this browser. INP is a field metric measured at the 75th percentile of page loads.
  • The busy work is a stand-in for real handlers and third-party code. Real pages differ.
  • Long Animation Frames, with script attribution, are only available in browsers that support them.

References

See more of my work