Interaction to Next Paint - Input Delay

Learn how to find and improve INP issues caused by input delays

Arjen Karel Core Web Vitals Consultant
Arjen Karel
linkedin

Interaction to Next Paint (INP) issues cause by input delay

In our previous article we talked about the interaction to next paint on how to identify interaction to next paint issues. If you would like to read up on the basics this is a great place to start!

In this article I will focus on 'Input Delay'. How this affects the Interaction To Next Paint issues and then explain how to minimize input delays to improve the interaction to next paint.!

INP TIP: most of the time the times input delay will occur during the early loading stages of the webpage!


What is input delay?

inp input delay schema

Input delay refers to the time it takes for the browser to begin processing an event callback after a user interacts with a web page (e.g., clicking a button or pressing a key). While there is always some input delay (even browsers need time to schedule the callbacks), input delay occurs when the browser is busy performing other scheduled tasks and cannot immediately schedule the callbacks requested by the interaction.

Input delay and the INP

The Interaction to Newt Paint (INP) can be broken down into 3 sub-part: 'Input Delay', 'Processing Time' and 'Presentation Delay'

inp 3 stage input delay highlighted

You might notice that there are naming similarities between the Input Delay and the older Core Web Vital 'First Input Delay'. For those that do not know: The Interaction to Next Paint is the successor of the retired 'First Input Delay'. The First input delay measured the time between the first interaction and the event callback. Even though the First Input Delay has been retired 'Input Delay' still plays and import role in improving web responsiveness because Input Delay is at the basis of every Interaction to Next Paint.

The importance of input delay

Since many developers think about improving the INP in terms of optimizing callback function (optimizing the process time) the 'Input Delay' is often overlooked. Granted, Input Delay is not usually the biggest part of the INP but nevertheless, if we optimize the INP delay we will often optimize all INP interactions at once!

inp distribution input delay highlighted

At CoreDash we collect millions of core web vitals data point each hour. Based on that data the Input Delay account for just 18% of the Interaction to Next Paint. And while that is not nearly as much as the Presentation Delay or the Processing time it is still a significant portion.

Input Delay causes:

Input delay occurs when the main thread is busy executing other tasks. These tasks can originate from:

inp input delay long task
  1. Early tasks. Normal, defered and asynced scripts that are enqueued early on will create early tasks
  2. Scheduled tasks. Some tasks do not run at the start of the pageload but might be scheduled for after the page has been loaded. These tasks can also interfere wtih the INP and cause an input delay. For example scripts that run after the window.onload event or scripts that get delayed by so-called optimization plugins.
  3. Repeat tasks. Recurring tasks via setInterval() that take a relatively long time to execute an co-occur with the INP
  4. Overlapping callbacks: Overlapping Callbacks are a common cause of input delay. Multiple callbacks scheduled close together can create a queue, delaying the processing of the next interaction.

Minimize input delay

To minimize input delay we need to ensure that the browser is not performing a (long) tasks right before the user interacts with a page. We can do this by scheduling taks to a more appropriate time, making sure tasks donit run for a long time or preventing interactions while tasks are running.
  1. Break up long early tasks into multiple smaller tasks. During a long tasks the browser cannot respond to user input while after each short task the browser can respond to user input. So break up long tasks with scheduler.yield() (experimental) or by wrapping each function in a timeout of 0 with setTimeout(callback,0)
  2. Manage interactive elements. Consider not presenting interactive elements (like a search bar) before the JavaScript code that controls them is fully loaded. This will prevent early clicks for element that are not ready to receive clicks. To optimize the UX for this pattern you could either prioritize loading the necessary JavaScript or temporarily hide/disable the element until it's functional.
  3. Idle Time Script Execution: Schedule non-critical scripts to run during browser idle periods with requestIdleCallback(). RequestIdleCallback runs when the browser is idle and does not need to process user input.
  4. 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.
  5. Check for input pending during repeat tasks. Before executing a set or scheduled tasks check for pending input before starting the tasks. If there is any input pending yield to the main thread first.
  6. Remove unneeded code. Regularly audit your scripts and remove any unnecessary code or even scripts because each line of code van potentially cause an input delay that affects the interaction to next paint.
async function yieldToMain() {
  if ('scheduler' in window && 'yield' in window.scheduler) {
    return await window.scheduler.yield();
  }
  return new Promise((resolve) => {
    setTimeout(resolve, 0);
  });
}

Practical Implications

Let's get to the most important question: 'What does this all mean for my site'. Let's break it down for WordPress & REACT.

WordPress

WordPress, due to it's nature, often comes with a theme and a large number of plugins. Both the plugins and the themes often rely on JavaScript for functionality. Since these plugins and themes are maintained by third party developers we have no control over the contents. This means that we cannot change the files and optimize 'bad code'. Even if the scripts behave nicely there is no guarantee that they will do so in the future.

So in order to minimize input delay and optimize the Interaction to Next Paint (INP) do the following:

  • Avoid using plugins whenever possible. While plugins are an easy way to add functionality, they often add scripts to the page. Those scripts will cause an input delay that impacts the INP. For each plugin ask yourself: Can I achieve the same functionality with custom code?
  • Choose Lightweight Themes. Many WordPress themes 'offer everything'. While that seems like a great idea it means that they likely are filled with functionality that is not used but does take up valuable CPU time.
  • Avoid page builders. Page builders like Elementor or WPBakery give you a a user-friendly, visual interface for building layouts. Unfortunately they often rely on scripts for presenting that lay-out to the visitors.
  • Only load scripts when they are needed. WordPress has a tendency to load all scripts on all pages. To fix this simply create a child theme and unregister unneeded scripts per page type. For example:
function my_deregister_scripts() {
  if ( ! is_page( 'contact' ) ) { 
    // Example: Deregister contact form script on non-contact pages
    wp_dequeue_script( 'contact-form-script' );
  }
}
add_action( 'wp_enqueue_scripts', 'my_deregister_scripts' );

REACT / NextJS

React of NextJS sites are mostly powered by JavaScript. Executing these scripts will take time and cause in input delay for the Interaction to Next Paint (INP)

  • Use server components. Server components are rendered on the server and not on the client which will lead to a reduced amount of JavaScript
  • Load third party scripts with the correct strategy. Load third party scripts after hydration of even during the browsers idle time
  • Implement an idle until urgent pattern: This pattern prioritizes user interactions over background tasks and created temporary states while the browser uses requestIdleCallback to perform non-critical tasks during browser idle periods.
  • Lazy load components. Lazy load components that are not immediately needed using React.lazy() or NextJS dynamic()
  • Use suspense for interactive components. Consider only client side rendering interactive components that need hydration to become interactive.

I help teams pass the Core Web Vitals:

lighthouse 100 score

A slow website is likely to miss out on conversions and revenue. Nearly half of internet searchers don't wait three seconds for a page to load before going to another site. Ask yourself: "Is my site fast enough to convert visitors into customers?"

Interaction to Next Paint - Input DelayCore Web Vitals Interaction to Next Paint - Input Delay