Have You Optimized for INP? ๐Ÿš€

If the user has to click twice to do one thing, this is called Rage Click and it is very annoying to any user, it happened to me personally in the past, on a random website I clicked on a hamburger menu one time but the the menu didnโ€™t show up and nothing happen so I get the feeling that I didnโ€™t click so I clicked again, and it ends up processing time is too long for the first click, it tries to open it, and processing the second click right after it and closed the menu again ๐Ÿ˜ก thatโ€™s why we were in need for some metric to measure that with is INP, our topic of day about interactivity.

Core Web Vitals ๐Ÿ“–

In 2020, Google came with an idea to enhance the user experience of the web user, they introduced some metrics to measure different parts of the user experience including the load time, visual stability, and interactivity, they named those as the Core Web Vitals (CWV).

What gave the CWV importance is that Google decided to make its score part of the search index for page, which means if you donโ€™t have at least p70 green in CWV then you will score lower in google search and might not appear in first page (this is a big deal specially for e-commerce websites)

For loading time, they decided to measure that by measuring the time your website take in order to load the Largest Contentful Paint, meaning the object on the screen above the fold that takes the largest area, they named it Largest Contentful Paint (LCP), this is different than the First Contentful Page (FCP) that was there before LCP, as FCP measures only the time it takes to paint the first pixel on the screen, which doesnโ€™t grantee the best loading experience to the user.

LCP in a webpage

For visual stability, researches show that one of the most annoying things that happen to a user is when they try to click on something and the layout get shifted and they mis-click something else, it happened a lot in the past when we had sites that were full of ads and each ad takes some more time to load and suddenly the page keep shifting the layout and you missed concentration on the content (very annoying, isnโ€™t it?), this metric is measuring the amount of shifting that might happen in the page overall, they named this metric Cumulative Layout Shift (CLS).

cart visually not stable

And for interactivity, they invented a metric called First Input Delay (FID), the main purpose for that metric was to measure the time your website takes in order to respond to the first user interaction with the page, something like a click or an input typing, and so on, but after some time, they discoverd that more than 90% or the users are usually interacting with a website after they feel that it is fully loaded, which makes FID is in the majority GREEN that makes it kind of useless for most performance reports, and thatโ€™s one of the reasons they through about INP as you will read in a bit.

What does FID measure? ๐Ÿ“

FID is to measure the interactivity of the user with your website, in particular the first input, but lets try to understand what exactly is happening behind the scene for measure FID and what does it measure exactly:

Chart explaining FID

As you can see from the chart above, FID is only measuring the time your website takes from the moment the user make an input (press a button for example) until your website start the response, doesnโ€™t matter how long it might take until the next paint, but at least your website start responding.

An that is being measured only for the first input, after loading the page, so if the user has any bad experience in a later input with no enough interactivity we will never know if we depend only on FID.

Whatโ€™s new in INP? โœจ

For all the reasons you just read above about FID, a new metric had to be made to make more sense in measuring user interactions, chrome team created a new metric to measure the Interaction to Next Paint (INP), it measures ALL the inputs of a user which makes it more critical to optimize, it also measure quite a different part than FID, not really measuring the start of the interaction only, but it measures until the next paint, including the processing time, that pushes developer to optimize in different ways.

INP metric explained

As you can see: it still start from the user input, measuring time of events, like mouse up, click and others, render processing, painting, until we have new frame on the screen, this can grantee that the user get an interactive experience for real.

Of course to measure a user input, it requires a real user, in synthetic testing it is impossible to measure, however in RUM testing it can be measured easily, you can see free reports about it now on CrUX ๐Ÿ”— for the websites that opt in for Chrome to gather anonymous analytics.

How to optimize for INP? ๐Ÿงช

Well as you understand what INP is measuring, INP is recommended to score under 200ms, meaning that you should respond to any input from a user within that time in order to raise the score of INP, now, letโ€™s dive into the reason for a poor INP score and how to optimize for it:

input recommendation

  • Break down long tasks: as you know, browsers are single threaded, meaning that everything is running on the Main Thread, the longer a task the busier the main thread will be, and also the longer an input from a user could be delayed, any task that takes longer than 50ms is considered a long task and it gets marked with a red flag as you can see below, so the first for that long tasks is to try to split them in the most granular way, in this case you are giving the main thread the chance to respond to any pending user input. long tasks in main thread
  • Use isInputPending ๐Ÿ”—: this is a new APIs that asks whether there is an input from the user pending and waiting for the main thread to get idle, this is very beneficial in case you have too long task that yow know, internally you can keep checking for a pending input and only yield to main thread if it returns true, here is the syntax:
if (navigator.scheduling?.isInputPending()) {...}

Hint: this is still experimental ๐Ÿ”— APIs that is not fully supported yet

  • Use postTask ๐Ÿ”—: this is another browser API that can be used to run tasks with priority in mind, so you can use one of 3 options for priority, either to have it user-blocking and that is the default, which means if the task is long it will block user interaction, or user-visible which works but stop only if there is a user input, or background and this one runs usually in a separate thread like a web worker and never interrupt user input.
scheduler.postTask(validateForm, { priority: 'user-blocking' });

Hint: this API has very limited support ๐Ÿ”— still but it is very promising

INP is a Core Web Vital (March 2024) ๐Ÿš€

From 12th of March 2024 (tomorrow), INP is a Core Web Vital, meaning that it will be part of the overall score for performance of your website, and will contribute to the google search ranking for your website, all of that makes it extremely important to spend time and effort to optimize for INP today.

Looking for a summary? I made a conf talk about INP in the past for React Summit US in 2023, here you can see the presentation ๐Ÿ”— and here is the recording ๐Ÿ”— only 8min, enjoy it, and share it.