Find and Fix Interaction to Next Paint (INP) issues
Learn how to identify and take care of Interaction To Next Paint issues
Find and Fix Interaction to Next Paint (INP) issues
In our previous article we talked about the interaction to next paint. If you would like to read up on the basics this is a great place to start!
In this article I will focus on identifying the different Interaction To Next Paint issues and then explain how to fix them!
INP TIP: most of the time the INP will be much worse when a user interacts with the page during the startup stage of page loading. That is why, when debugging the INP it makes sense to log all interactions as well as the page loading state!
Table of Contents!
Step 1: Check the INP in search console
"The first step to recovery is admitting that you have a problem". So before we do anything to fix the Interaction to Next Paint let's make sure that we really have a problem with the interaction to next paint.
Log in to your Google Search Console. In the left menu click Core Web Vitals and select either Mobile or Desktop (tip: most of the times INP issues are on mobile, so start with mobile)
Here you will see an overview of all Core Web Vitals related issues that are currently on your site. If one of these issues is INP related we have confirmed there is a problem!
Step 2: Identify Interaction to Next Paint issues
Google Search console does not give you any information apart from URL groups to figure out what is causing the problems with the Interaction to Next Paint. So most of the time I see developers just blindly going in. They start removing unused JavaScript (always, a great idea) and breaking up the main thread (also a great idea) but that hardly ever fixes the INP completely.
That is why, when improving the INP, we will need to know exactly what is going in.
Which elements, when interacted with cause a bad INP Score. Usually a bad INP score is not caused by one single element but a combination of issues. We need to tackle them one by one, starting with the worst ones and working our way up.
When do these Interactions happen? Do they happen during the start-up phase of page load or do they happen even when the main page
Where do these interactions happen? Do they happen on every page or do they happen only on a few selected pages.
How can we replicate these interactions? You might have found out by now that is is hard to replicate INP issues. That is why we need to set ourselves up for success by mimicking device characteristics with a bad INP score.
Set up RUM tracking
To answer all these questions we need to start tracking real users and log any of the problems that might happen with the Interaction to Next Paint. There are several ways to enable RUM tracking. The first is by leveraging the Web Vitals library and sending the results to your own analytics backend. The upside to this method is that it is cheap and flexible. The downside is that it might be a lot of extra work.
A good alternative to sending your Core Web Vitals data to your own backend is by using one of the many RUM tools out there. We have developed Core/Dash just for these use cases. Core/Dash is a low cost, fast and effective RUM tool that just gets the job done! Of course there are many RUM solutions out there and they will also do the job (at a higher price though)
Find slow interactions per element that cause a high INP
The first thing that needs to be done is find the 'slowest' interactions that cause the worst time to first byte scores. Just list your pages by 'INP metric by Elements' in CoreDash and you will get your slowest interactions. Click on the first line to filter your metrics by these interactions.
Find when bad INP interactions occur
Next sort the filtered URLs by load state. This will give you more insight into the root cause of the INP. In this case the high INP happens when the DOM content has been loaded. This means scripts have been parsed but async scripts an the page's sub-resources have not yet been loaded. In this case the INP is caused by early clicks when the page load has not completely finished!
Continue by clicking the load state with the highest impact to create another filter!
Find URLs responsible for high INP scores
Finally when we have filtered for the elements with the slowest interaction and the correct load state we are going to take a look at the URL's where the INP is at its worse. In this case this clearly happens on a specific set of pages.
Find device characteristics
Finally, when we have identified slow interactions, load state and urls that cause a high Interaction to Next Paint we are going to take a look at what types of visitors cause the worst INP scores. We would look at Device Memory, Bandwidth, Screen size etc. Once we have identified these characteristics we can move on to replicating and logging the issue!
Step 3: replicate and debug interactions that cause a high INP score
Once we have all the information that we need we can start to dig deep into the underlying issues of the Interaction to Next Paint.
Set yourself up for success: replicate the INP failing circumstances
The next thing we should do is try and recreate the failing INP. We do this by mimicking the circumstances where the INP might be failing.
Use the Chrome Performance Panel: Open the chrome developer tools (Ctrl-Shift-i) and select the performance panel. In the top bar you can select the CPU Throttle (throttle it to 4x slowdown to emulate a normal mobile device), the Network Throttle (select the fast 3g preset to mimic your average mobile device) and set the hardware concurrency to 4 or 8 to mimic your average mobile.
To load chrome with less memory available (although lowering the network and CPU setting will often do the job!) start up chrome in a docker container and assign less memory.
Reload the page, interact and check the INP with the Core Web Vitals visualizer
The next step to finding the cause of the bad INP scores is to simulate the conditions and confirm that the INP scores are indeed as bad as reported.
Reload page and click on the right element at the right time
Debug the INP with a performance trace
This is the moment you have been preparing for in the previous steps. It is time to find out why a certain interaction is causing the bad Interaction To Next Paint score.
Open the Chrome Developer Console again (Ctrl-Shift-i), navigate to the Performance panel and this time click the Circular Arrow icon to reload the page and start recording (or use the Ctrl-Shift-E shortcut).
Open the Chrome Developer Console again (Ctrl-Shift-i), navigate to the Performance panel and this time click the Circular Arrow icon to reload the page and start recording (or use the Ctrl-Shift-E shortcut).
Step 3: Fix INP issues
We are now at a point where we know what interaction is causing our bad INP and we have analyzed exactly what is going on during this slow interaction. This means it is time to start fixing the Interaction to Next Paint. The Interaction to Next Paint can be broken down into 3 phases: 'input delay', 'processing time' and 'presentation delay'.
Each phase of the interaction to next paint should be treated differently!
Minimize Input Delay:
Input delay is the time between the interaction with the page to when the event callback begin to run. While there is always some input delay (even browsers need time to schedule the callbacks) there are a few things to consider:
- Avoid long tasks. Whenever a task runs it will block the main thread and leave the event callbacks waiting. This is especially important when optimizing early clicks (since most script will be executing at that time).
- Be careful when creating new tasks. For example recurring tasks via
setTimeout()
or tasks that will probably occur before the INP event like callbacks on themouseover
event. - Measure and assess early interaction. When an interactive element is presented early (for example a site search element) and is controlled by JavaScript that loads later, any interaction with the element will not trigger an immediate layout update. Either prioritize the functionality or hide/disable the element before it's properly working.
- Use web workers to run JavaScript off the browser's main thread. Web workers allow Script to run off the main thread. This will prevent the main thread from blocking and cause INP input delay issues
- Load nice-to-have third party scripts during browser idle time. Some scripts are more critical then others. It makes sense to prioritize these scripts and load less important scripts during browser idle time. For example a chat script
Minimize processing time
- Remove unneeded code. Unneeded code is either older code that still runs or new code that is not needed on this specific page but still takes up CPU time. This is by far the easiest way to immediately improve the INP.
- Defer Code that does not need to run before the next paint. Split up code in critical code that must run before the INP and non-critical code (for example sending analytics) and schedule that after the INP even with the
requestIdleCallback()
method. - Optimize code that must run before the paint. Check your code and rewrite slow or ineffective parts.
- Provide immediate feedback. On complicated or possible slow tasks provide immediate feedback before running the main code.
Minimize Presentation Delay
- Keep the DOM small and simple. Basically it will be much easier for a browser to render a page with few and simple unnested DOM elements (html nodes) then it is to render a page with many nested DOM nodes.
- Use content-visibility to lazy-render off-screen content. Content-visibility will speed up rendering of visible parts of the page by delaying rendering of off screen content by rendering that off screen content just-in-time.
Stop Guessing, Start Measuring
I use Core/Dash to optimize my clients sites. So Should You.
- Easy set up.
- Over 5000 happy clients
- Free trial, No strings attached