The three phases of every interaction
- Input delay — waiting for the main thread to be free to run the handler.
- Processing time — executing the event handler code.
- Presentation delay — recalculating layout and painting the next frame.
How to improve INP
The key is unblocking the main thread: breaking up long tasks (yielding), reducing and deferring JavaScript, avoiding unnecessary re-renders, and limiting expensive DOM operations inside event handlers.
Example
A heavy synchronous operation in a click handler blocks the main thread and delays the next paint. Breaking work into smaller chunks (yielding) lets the browser respond faster.
button.addEventListener('click', () => {
for (let i = 0; i < 50000; i++) {
processItem(items[i]); // blocks the main thread
}
updateUI();
});button.addEventListener('click', async () => {
for (let i = 0; i < items.length; i++) {
processItem(items[i]);
if (i % 100 === 0) await new Promise(requestAnimationFrame);
}
updateUI();
});