Skip to article
PerformanceOct 20, 20265 min read

Why the site slows down after a click: INP, JavaScript and message queues

Diagnose slow clicks and typing with INP, JavaScript analysis and Worker message queues. A practical workflow using Milten’s INP Scanner and JS Scanner.

Button interaction and glowing messages between the main thread and a Worker

A filter takes time to update, a menu opens late, or typed text appears with a delay—even though the page loads quickly. Investigate responsiveness after each action and the JavaScript work involved. In applications using Workers or iframes, this also means examining message exchange.

Why a fast site may be slow to respond to actions

After the click, the browser needs to handle the event, execute JavaScript and show the updated frame. If the main thread is busy, some work waits its turn. Therefore, good loading speed does not guarantee fast response of menus, filters and forms.

Moving calculations to a Web Worker can free up the main thread, but it adds data exchange. The page window, Workers and iframes exchange messages through postMessage(). A sent message may have to wait before it is processed.

Where delays occur in the message queue

Start with three possible reasons:

  • The receiver is running a long synchronous task. A new message must wait until its thread is available.
  • Too many messages arrive. Even short handlers can build up a queue when work arrives faster than it can be processed.
  • Large amounts of data are exchanged. Serialization at the sender and deserialization at the receiver take time on their respective threads.

For example, a search sends a new request to a Worker after every typed letter. If it is still calculating the previous result set, requests accumulate. The user has finished typing, but the application is still computing results for old input. Measure message frequency, processing time and the amount of data exchanged.

How INP measures page response

INP, Interaction to Next Paint, evaluates the page’s responsiveness to clicks, taps and keystrokes during the visit. The resulting value represents one of the slowest interactions given the outlier exclusion rules. The latency of an individual interaction consists of waiting for processing to begin, the execution of handlers, and the time until the next frame is shown.

A good INP value is no more than 200ms. The range above 200 to 500 ms requires improvement, above 500 ms is considered poor. To evaluate a site, the 75th percentile of visits is used separately on mobile and desktop devices.

The message queue can contribute to this latency when its processing occupies the main thread and interferes with input or rendering. But the Worker response time cannot be automatically considered INP.

Let's return to the search: the entered letter may appear immediately, and the results will be updated later. The next frame has already been shown, although the useful work has not yet been completed. In such a scenario, measure response to input and time to actual results separately. A fast loading indicator does not prove that the search itself has become faster.

INP checking and JavaScript analysis in Milten

INP check helps to investigate interaction delays in a test run. Select the page with the problematic action: menu, catalog, form or cart. In the report, check which interactions were completed and what causes of delays were found. The conclusion applies to this run and its conditions.

JS Scanner analyzes JavaScript during a single page load in Chromium, without clicks or scrolling. It reports script sizes and loading, code execution, long tasks, errors and scripts with a different hostname. A view of modules inside bundles is available when the site supplies usable source maps.

Compare reports to select an area to inspect. A heavy file in JS Scanner may explain the load when starting the page, but its presence does not yet prove the reason for the slow click. The behavior after loading needs to be reproduced separately. Both tools help you narrow your search; they do not provide a trace of every message between all windows and workers.

Code that did not execute during loading may be needed after a click or in another page state. Test those scenarios before removing it. A script with a different hostname is not necessarily unnecessary: the project’s own CDN may fall into this group.

How to find the cause of a bad INP

  1. Record the steps to reproduce the issue. Specify the page, device and interface state. For example: open a catalog, type a query quickly, then select a filter.
  2. If RUM or CrUX data is available, use it to prioritize problems seen in real visits. A lab run does not replace field statistics.
  3. Run an INP check and compare its coverage with the problematic action. If that action was not reproduced, investigate it separately in the browser.
  4. Inspect JavaScript loading with JS Scanner. Identify suspicious files and long tasks that may coincide with the delay.
  5. Record the scenario in DevTools. For a Worker or iframe, trace message sending, processing start, response and screen update. Request IDs distinguish responses to old input from current results.
  6. After the fix, repeat the steps with the same device, CPU and network settings. Compare several runs, then check field data as it accumulates.

What to change to optimize INP

INP optimization begins by reducing the work that delays the next frame. Reduce synchronous handlers, break up long tasks, and let the browser render feedback before unnecessary calculations.

In an application with a Worker, check to see if all the work being submitted is needed. For searches, you can aggregate frequent updates and discard outdated results. Select the sending delay according to the behavior of the interface: too much debounce will itself slow down the search for the user.

Limit messages to the data the receiver needs. After a filter changes, sending query parameters may be sufficient instead of the entire catalog. For suitable binary data, consider transferable objects. Account for the transfer of ownership: the sender can no longer use a transferred buffer.

Test each hypothesis separately. If you have reduced the size of the message, compare the transmission and processing time. If you moved the calculation, check the interface response and time to result. This will show which edit helped.

Is it possible to automatically see queue overload?

The WICG proposal now pursues an extension to the Long Animation Frames API to detect sustained task-queue congestion in documents and Workers. Per-message timings and serialization costs are outside the current extension’s scope.

This remains an experimental proposal. Do not make diagnostics depend on the early delayed-message observation examples. Start with a reproducible user flow, INP Scanner, JavaScript analysis and a DevTools recording. Choose one slow action and trace the whole path to the result the user needs.

Website speed check

Find out what slows your website down

Check your page with Milten to see its Core Web Vitals and get recommendations for faster loading.

Check your website
Cookies

We use cookies

We use cookies to give you a better experience on our site. You can learn more about how we use cookies in our privacy policy.

Why the site slows down after a click: checking and optimizing INP