Meet the new Core Web Vital: Interaction to Next Paint (INP) 🎨
Tags: webdev, performance, programming, tutorial
Published: 2023-08-11 09:05:43

In March 2024, Interaction to Next Paint (INP) will replace one of the current Core Web Vitals, First Input Delay (FID).

This is a big deal since Core Web Vitals affect both user experience and your organic rankings on Google (Core Web Vitals became a part of Google's ranking algorithm in 2021).

Before we dive into what Interaction to Next Paint (ICP) is, let's do a quick recap by answering the following questions:

- What are Core Web Vitals?
- Why are they important?

_💡 If you're already familiar with Core Web Vitals, you can skip to the "Meet the new kid on the block: INP"-section._

## What is core Web Vitals?

![Core Web Vitals](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/o7fvizcxe6cfubhy6h01.png)

_Image source: [https://web.dev/vitals/](https://web.dev/vitals/)_

Core Web Vitals represent a trio of essential user-centric metrics introduced by Google for evaluating and enhancing website performance. These three are:

**Largest Contentful Paint (LCP):** This metric measures the time the largest visible element takes to appear, influencing the perceived speed of a website's loading process.

**First Input Delay (FID):** FID measures the responsiveness of a webpage by quantifying the delay between a user's initial interaction (e.g., clicking a button) and the browser's ability to respond. It indicates how smoothly users can interact with a site.

**Cumulative Layout Shift (CLS):** CLS evaluates visual stability by calculating unexpected layout shifts during page load. These shifts can lead to accidental clicks or confusing user experiences. CLS aims for a smooth loading process without abrupt visual changes.

These metrics collectively offer insights into the user experience journey on a website, covering loading efficiency, interactivity, and visual consistency.

## Why are Core Web Vitals important?
![User being frustrated by a poor user experience](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yupuk671cskzi4j2eozy.jpg)

_A poor user experience can both frustrate and infuriate users._

There are multiple reasons why it's essential to consider Core Web Vitals when developing a website, for instance:

**User Experience (UX):** Core Web Vitals directly address the factors that influence how users perceive and engage with websites. Websites can create a smoother and more satisfying user journey by focusing on loading speed, interactivity, and visual stability.

**Search Engine Optimisation (SEO):** Google has integrated Core Web Vitals into its ranking algorithm, making them a critical element for search engine optimisation. Websites that excel in these metrics are more likely to rank higher in search results, leading to increased visibility and organic traffic.

**Conversion Rate Optimisation (CRO):** Core Web Vitals are crucial in CRO strategies. Improved user experience, stemming from better loading times and interactivity, directly contributes to higher conversion rates. Users are more likely to complete desired actions when they have a seamless and engaging website experience.

Now let's look at the new Core Web Vital that will replace First Input Delay (FID): The new metric, Interaction to Next Paint (INP).

## Meet the new kid on the block: INP
![The new kid on the block: INP](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/skeqhc2mud3sucm28xyu.jpg)

You can think of Interaction to Next Paint (INP) as First Input Delay (FID) on steroids 💉

Where FID only measures the first interaction, INP measures all page interactions. That means you get the latency of all the interactions the user has made with a page.

However, you are not getting the value (metric) of each interaction, but instead, a single value which all / nearly all interactions were below (longest interaction observed, ignoring outliers). INP gets calculated when the user leaves the page.

So, where FID tells you something about the first impression, INP tells you something about the overall experience. 

A low INP will indicate that the page consistently responded fast to all (or the vast majority) of user interactions.

But why switch out FID with INP? According to Chrome usage data, users spend roughly 90% of the time on a page after it loads. Therefore, responsiveness throughout the page lifecycle is essential in determining the overall user experience. The INP metric precisely evaluates this aspect.

The goal is to provide good responsiveness to the user, which comes when the page responds quickly to the user's interaction. This response will be some sort of visual feedback. Visual feedback tells the user if an item has been added to the shopping cart, a login form is being authenticated, etc.

INP is not about showing the "end result" as quickly as possible but to cue the user that something is happening.

An interaction might be highly complex and take a long time. INP doesn't care how long a network fetch takes but rather how quickly you display visual feedback to the user. This could be with a loading spinner. INP only wants to know how long the next paint is blocked.

Why? Because poor responsiveness can cause multiple unintended responses (e.g., clicking a button too many times), which results in a poor user experience.

We've talked a lot about interactions, so let's look at exactly what an interaction is.

### What is an interaction?
![Interaction illustration](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jekw5vgc7pl38qipuafk.png)

_Image source: [https://web.dev/inp/](https://web.dev/inp/)_

The interactivity is often happening through JavaScript. However, native browser controls like checkboxes, radio buttons, and CSS-powered controls also provide interactivity.

INP doesn't measure all interaction types, but only:

- Mouse clicking
- Tapping on a touchscreen
- Keystrokes (pressing a key on a keyboard)

This means that INP does not measure hovering and scrolling unless the user scrolls with their keyboard (space, page up/down, etc.) since this is a keystroke.

It's also important to note that an interaction may consist of multiple parts. For instance, when you hit a key, you trigger the [keydown](https://developer.mozilla.org/en-US/docs/Web/API/Element/keydown_event) and the [keyup](https://developer.mozilla.org/en-US/docs/Web/API/Element/keyup_event) events. In this case, the event with the longest duration within the interaction is chosen for the interaction's latency.

How many interactions there are on a website depends on the type of website/page. If a page is made up of mostly text and images, there may be few or no interactive elements. If, on the other hand, the page includes a text editor or a game, there could be hundreds or even more interactions.

### What is a good INP?
![Interaction to Next Paint (INP) rating](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sekmuy6n9n7hheufdldu.png)

_Image source: [https://web.dev/inp/](https://web.dev/inp/)_

It can be challenging to rate responsiveness as "good" or "poor" since the capability of a user's device can vary a lot (e.g., older vs newer devices).

However, a good rule of thumb is to measure the 75th percentile of page loads (segmented across mobile and desktop devices). Then a **good** INP would be below or at **200 ms**. If the INP is between **200 ms** and **500 ms**, your page's responsiveness needs improvement. Everything above **500 ms** means that your page has poor responsiveness.

### How do you measure INP?
The best way to measure INP is by using "field data", which refers to real-world performance data collected from users interacting with your website.

One way to get these field data is to use the Chrome User Experience Report (CrUX) – if your website qualifies for inclusion. You can find the CrUX in [Pagespeed Insights](https://pagespeed.web.dev/).

Another way to get field data is by using a Real User Monitoring tool (RUM) like [SpeedCurve](https://www.speedcurve.com/). If you're using a framework like Next.js (v10+), Nuxt.js (v2+), or Gatsby (v2+), you can also use [Vercels Speed Insights](https://vercel.com/docs/concepts/speed-insights).

You can also test INP "in the lab" (synthetic testing), but it's recommended to have field data so that you can reproduce and identify slow interactions.

Read more about how to [diagnose slow interactions in the lab](https://web.dev/diagnose-slow-interactions-in-the-lab/).

💡 Tip: If you don't have any field data, the Total Blocking Time (TBT), which assesses page responsiveness during load, correlates very well with INP.

**Can INP always be measured?**
No, there are times when INP isn't measured, for instance:

- The user never "interacted" (clicked, tapped, or pressed a key) - with the page.
A bot accessed the page (e.g., a crawler or a headless browser).

### How to optimize INP?
Before we can optimise INP, we need to know one crucial thing. Can you guess _what_ it is?

We need to know what to optimise.

![Rolling eyes](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kexlitha46vil6tu22oa.gif)

Yes, I know it seems obvious. But unlike other web vitals, such as Largest Contentful Paint (LCP), finding which interactions are slow can be difficult.

Ideally, you already have loads of field data showing which interactions need to be optimised.

Unfortunately, in the real world, this isn't always the case.

Maybe you don't have any Real User Monitoring (RUM) implemented on your site. Perhaps you don't have the required traffic amount to be present in the CrUX reports. Or maybe it's an entirely new site that you want to ensure performs well before shipping it.  

So, let's see how we can find and diagnose these slow interactions "in the lab".

#### Diagnosing INP in the lab
To diagnose INP in the lab, you will need a Chrome browser and the [Web Vitals Chrome Extension](https://web.dev/diagnose-slow-interactions-in-the-lab/).

Once installed, locate the extension and open it. Click on the gear icon (settings) in the bottom right corner. Enable Console logging and click save.

Now all interactions will be logged into your console (You can open the console using the keyword shortcut _Ctrl + Shift + J_ on Windows and _Cmd + Opt + J_ on Mac), including other web vitals.

![Interactions logged to the console](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/v3igybak7oxq28wmoubs.png)

Next, it's time to put in the legwork. You need to go through your site interactions to test if any interactions need improvement.

If you have a larger site, you can write down common user flows and test them out. For instance, if you have an e-commerce site, the flow and interactions could look something like this:

1. Click on a product.
2. Select a variant (e.g., size, colour).
3. Select quantity.
4. Click "Add to cart".
5. Click the cart icon in the header.
6. Click the "Go to checkout"-button.
7. Apply a discount code.
8. Fill out the shipping address.
9. Choose a shipping option.
10. Go to payment.

Remember, the more interactions you can test, the better. For instance, you may find that the discount field is performing slowly without showing any loading indicator. Or maybe the Postal code field, which automatically fills out the City field, is the sinner.

Once you have been through all interactions (or the most common ones), you should have a list of interactions which need improvement. If you don't have any, give yourself a pad on the back and take a break.

If you're not that lucky, we will look into how we optimise the interactions.

#### Optimise interactions
Now you should have identified one or more slow interactions you can reproduce.

An interaction can be split into three phases:

1. **The input delay:** Starts when the user initiates an interaction and ends when the event callbacks begin to run.
2. **The processing time:** The time it takes for event callbacks to run to completion.
3. **The presentation delay:** The time it takes for the browser to present the next frame.

Add these three together, and you get the total interaction latency.

##### Reducing Input delay
Input delay, the time from user interaction initiation to event callback execution on a website, plays a crucial role in determining the responsiveness of web interactions. These are some of the ways we can reduce input delay.

**Prioritise Brief Interactions:** Shortening the duration of interactions is key to meeting the Interaction to Next Paint (INP) metric. While eliminating input delay entirely is challenging, focusing on reducing main thread workload during user interactions can significantly enhance responsiveness.

**Optimise Timer Usage and Animation:** Be careful about employing JavaScript timers like [setTimeout](https://developer.mozilla.org/docs/Web/API/setTimeout) and [setInterval](https://developer.mozilla.org/docs/Web/API/setInterval). Instead, try to use CSS animations over JavaScript animations, as they minimise the accumulation of animation frames that can cause delays.

**Manage Long Tasks:** Long tasks on the main thread contribute to extended input delays. Optimise task workload and consider breaking down lengthy tasks into smaller segments using yielding to improve overall responsiveness.

**Address Interaction Overlap:** Interaction overlap, where subsequent actions interrupt the rendering of the initial interaction, can worsen input delay. Use techniques like [debouncing](https://web.dev/debounce-your-input-handlers/) for user inputs and the [AbortController](https://developer.mozilla.org/en-US/docs/Web/API/AbortController/abort) to manage resource-intensive interactions.

##### Optimising Event Callbacks
After tackling input delay, the focus shifts to ensuring these callbacks respond swiftly to user interactions. Here are some of the ways we can optimise these callbacks.

**Frequent Main Thread Yielding:** Prioritise minimising work within event callbacks. Break tasks into smaller units using techniques like setTimeout to prevent long tasks from obstructing the main thread. This approach enhances overall responsiveness.

**Efficient Rendering with Yielding:** Yield immediately after an event callback that updates the UI to expedite rendering. Advanced techniques involve structuring code to prioritise rendering-critical tasks, deferring non-critical ones for subsequent tasks.

**Preventing Layout Thrashing:** Avoid synchronous layout issues (layout thrashing) by refraining from updating and immediately reading styles within the same task. Be cautious of properties causing this problem in JavaScript.

##### Minimising Presentation Delay
Now it's time for the presentation, where we need to minimise the delay as much as possible. The presentation delay occurs between event callbacks' completion and the browser painting the next frame to reflect interaction changes.

**Reducing DOM Size:** Smaller DOMs lead to quicker rendering, while larger DOMs increase workload. Efforts like flattening the DOM or strategically adding elements help, though large DOMs may remain challenging.

**Lazy Rendering with content-visibility:** Utilise CSS's content-visibility to render elements as they approach the viewport. It cuts rendering time, benefiting the Interaction to Next Paint (INP) metric.

**Smart HTML Rendering via JavaScript:** JavaScript-rendered HTML impacts performance, involving parsing, styling, and rendering. Balancing initial HTML with JavaScript content updates avoids delayed frame presentation.

## Acknowledgement
These great articles have been used as the basis of this article. Some explanations have been quoted directly to avoid confusing the reader.

- Interaction to Next Paint (INP): [https://web.dev/inp/
](https://web.dev/inp/)
- Optimise Interactions to Next Paint: [https://web.dev/optimize-inp/](https://web.dev/optimize-inp/)
- Diagnose slow interactions in the lab: [https://web.dev/diagnose-slow-interactions-in-the-lab/](https://web.dev/diagnose-slow-interactions-in-the-lab/)
- Optimise input delay: https://web.dev/optimize-input-delay/

If you need to dive into the subject of INP even more, I recommend starting here: [https://web.dev/how-to-optimize-inp/](https://web.dev/how-to-optimize-inp/)