How do modern frameworks perform on the new INP metric

Understand how the new INP metric affects the experience of sites built using JavaScript frameworks and libraries.

Leena Sohoni
Leena Sohoni
Addy Osmani
Addy Osmani
Keen Yee Liau
Keen Yee Liau

Chrome recently introduced a new experimental responsiveness metric in the Chrome UX Report report. This metric, which we now know as Interaction to Next Paint (INP) measures overall responsiveness to user interactions on the page. Today we want to share insights on where websites built using modern JavaScript frameworks stand in relation to this metric. We want to discuss why INP is relevant to frameworks and how Aurora and frameworks are working to optimize responsiveness.

Background

Chrome uses First Input Delay (FID) as part of Core Web Vitals (CWV) to measure the load responsiveness of websites. FID measures the waiting time from the first user interaction to the moment the browser is able to process the event handlers connected to the interaction. It does not include the time to process the event handlers, process subsequent interactions on the same page, or paint the next frame after the event callbacks run. However, responsiveness is crucial to the user experience throughout the page lifecycle because users spend roughly 90% of the time on a page after it loads.

INP measures the time it takes a web page to respond to user interactions from when the user starts the interaction until the moment the next frame is painted on the screen. With INP, we hope to enable an aggregate measure for the perceived latency of all interactions in the page's lifecycle. We believe that INP will provide a more accurate estimate of web pages' load and runtime responsiveness.

Since FID measures only the input delay of the first interaction, it is likely that web developers have not proactively optimized the subsequent interactions as part of their CWV improvement process. Sites, especially those with a high degree of interactivity, would therefore have to start working hard to do well on this metric.

The role of frameworks

Since many websites rely on JavaScript to provide interactivity, the INP score would primarily be affected by the amount of JavaScript processed on the main thread. JavaScript frameworks are an essential part of modern front-end web development and provide developers with valuable abstractions for routing, event handling, and compartmentalization of JavaScript code. Thus, they have a central role in optimizing the responsiveness and user experience of websites that use them.

Frameworks may have taken steps for better responsiveness by improving FID for websites earlier. However, they would now have to analyze the available responsiveness metric data and work towards addressing any gaps identified. In general, INP tends to have lower pass rates, and the difference in the measurement process requires additional code optimization. The following table summarizes why.

FID INP
Measurement Measures the duration between the first user input and the time when the corresponding event handler runs. Measures the overall interaction latency by using the delay of the
Depends on Main thread availability to run the event handler required for the first interaction. The main thread could be blocked because it is processing other resources as part of the initial page load. Main thread availability and size of the script executed by the event handlers for different interactions, including the first interaction.
Primary cause for poor scores Poor FID is mainly caused due to heavy JavaScript execution on the main thread. Heavy event-handling JavaScript and other rendering tasks after running handlers can result in poor INP.
Optimization FID can be optimized by improving resource loading on page load and optimizing JavaScript code. Similar to FID for every interaction plus usage of rendering patterns that prioritize key UX updates over other rendering tasks.
FID versus INP: Measurement and optimization

The Aurora team in Chrome works with open-source web frameworks to help developers improve different aspects of the user experience, including performance and CWV metrics. With the introduction of INP, we want to be prepared for the change in CWV metrics for framework-based websites. We have collected data based on the experimental responsiveness metric in CrUX reports. We will share insights and action items to ease the transition to the INP metric for framework-based websites.

Experimental responsiveness metric data

An INP below or equal to 200 milliseconds indicates good responsiveness. The CrUX report data and the CWV Technology Report for June 2023 give us the following information about responsiveness for popular JavaScript frameworks.

Technology % Passing
% Mobile Desktop
Angular (v2.0.0+) 28.6 83.6
Next.js 28.5 87.3
Nuxt.js 32.0 91.2
Preact 48.6 92.8
Vue (v2.0.0+) 50.3 94.1
Lit 50.0 88.3
CWV technology report - INP data for June 2023

The table shows the percentage of origins on each framework with a good responsiveness score. The numbers are encouraging but tell us that there is much room for improvement.

How does JavaScript affect INP?

INP values in the field correlate well with the Total Blocking Time (TBT) observed in the lab. This could imply that any script that blocks the main thread for a long duration would be bad for INP. Heavy JavaScript execution after any interaction could block the main thread for an extended period and delay the response to that interaction. Some of the common causes that lead to blocking scripts are:

  • Unoptimized JavaScript: Redundant code or poor code-splitting and loading strategies can cause JavaScript bloat and block the main thread for long periods. Code-splitting, progressive loading, and breaking up long tasks can improve response times considerably.

  • Third-party scripts: Third-party scripts, which are sometimes not required to process an interaction (for example, ad scripts), can block the main thread and cause unnecessary delays. Prioritizing essential scripts can help to reduce the negative impact of third-party scripts.

  • Multiple event handlers: Multiple event handlers associated with every interaction, each running a different script, could interfere with each other and add up to cause long delays. Some of these tasks may be non-essential and could be scheduled on a web worker or when the browser is idle.

  • Framework overhead on event handling: Frameworks may have additional features/syntax for event handling. For example, Vue uses v-on to attach event listeners to elements, while Angular wraps user event handlers. Implementing these features requires additional framework code above vanilla JavaScript.

  • Hydration: When using a JavaScript framework, it's not uncommon for a server to generate the initial HTML for a page which then needs to be augmented with event handlers and application state so that it can be interactive in a web browser. We call this process hydration. This can be a heavy process during load, depending on how long JavaScript takes to load and for hydration to finish. It can also lead to pages looking like they are interactive when they are not. Often hydration occurs automatically during page load or lazily (for example, on user interaction) and can impact INP or processing time due to task scheduling. In libraries such as React, you can leverage useTransition so that part of a component render is in the next frame and any more costly side-effects are left to future frames. Given this, updates in a transition that yield to more urgent updates like clicks can be a pattern that can be good for INP.

  • Prefetching: Aggressively prefetching the resources needed for subsequent navigations can be a performance win when done right. If however, you prefetch and render SPA routes synchronously, you can end up negatively impacting INP as all of this expensive rendering attempts to complete in a single frame. Contrast this to not prefetching your route and instead kicking off the work needed (for example, fetch()) and unblocking paint. We recommend re-examining if your framework's approach to prefetching is delivering the optimal UX and how (if at all) this may impact INP.

From now on, for a good INP score, developers will have to focus on reviewing the code that executes after every interaction on the page and optimize their chunking, rehydration, loading strategies, and the size of each render() update for both first-party and third-party scripts,

How are Aurora and frameworks addressing INP issues?

Aurora works with frameworks by incorporating best practices to provide baked-in solutions to common problems. We have worked with Next.js, Nuxt.js, Gatsby, and Angular on solutions that offer strong defaults within the framework to optimize performance. Following are the highlights of our work in this context:

  • React and Next.js: The Next.js Script component helps to address issues caused due to inefficient loading of third-party scripts. Granular chunking was introduced in Next.js to allow for smaller-sized chunks for shared code. This helps to reduce the amount of unused common code that is downloaded on all pages. We are also working with Next.js to make INP data available as part of their Analytics service.

  • Angular: Aurora is partnering with the Angular team to explore server-side rendering and hydration improvements. We also plan to look into refinements in event handling and change detection to improve INP.

  • Vue and Nuxt.js: We are exploring avenues for collaboration, mainly in relation to script loading and rendering.

How are frameworks thinking about improving INP?

React and Next.js

React.js time slicing, implemented through startTransition and Suspense, allows you to opt-in to selective or progressive hydration. This means that hydration isn't a synchronous block. It's done in small slices that are interruptible at any point.

This should help improve INP and enable you to respond more quickly to keystrokes, hover effects during the transition, and clicks. It also helps to keep React apps responsive even for large transitions such as auto-complete.

Next.js has implemented a new routing framework that uses startTransition by default for route transitions. This allows Next.js site owners to adopt React time-slicing and improve the responsiveness of route transitions.

Angular

The Angular team is exploring several ideas that should also help with INP:

  • Zoneless: Cuts down on initial bundle size, and required code that must load before an app can render anything.
  • Hydration: Island-style hydration to limit how much of the app needs to be woken up for interaction.
  • Reduce overhead of CD: For example, make change detection less expensive, find ways to check less of the app, and leverage reactive signals about what's changed.
  • More granular code-splitting: Make the initial bundle smaller.
  • Better support for loading indicators:: For example, during SSR re-render, during route navigation, and in lazy loading operations.
  • Profiling tools: Better dev tools to understand interaction cost, particularly around change detection cost for specific interactions.

Through these enhancements, we can address different issues that lead to poor responsiveness and user experience, and boost the CWV metrics and the new INP metric for framework-based websites.

Conclusion

We expect the INP score to provide a better compass for websites to improve responsiveness and performance in the future. We will build on our existing INP guide to provide more actionable tips for framework developers in 2023. We hope to achieve this by:

  • Creating channels for easy access to field data on INP for frameworks and web developers.
  • Work with frameworks to build features that will improve INP by default.

We welcome feedback from framework users as they begin their INP optimization journeys.