INP : optimiser la réactivité perçue de son site

· 7 min de lecture

L’Interaction to Next Paint a remplacé le FID dans les Core Web Vitals. Comment le mesurer et les techniques concrètes pour l’améliorer.

En bref

Quand on clique sur un site, la page doit réagir tout de suite. Google mesure ce délai avec un indicateur, l’INP. L’article explique comment le mesurer et le réduire.

Un mot technique vous échappe ? Le glossaire du développement web l’explique simplement.

Le First Input Delay ne mesurait que le délai avant le traitement de la première interaction. L’INP mesure la latence de toutes les interactions de la visite, jusqu’à l’affichage suivant. Un bon score est inférieur à 200 ms. Optimiser l’INP, c’est donc améliorer la réactivité perçue de son site : celle que ressent réellement le visiteur à chaque clic. Les Core Web Vitals font aussi partie des signaux de classement de Google, en complément du SEO technique d’une page (voir « Next.js : soigner son SEO avec l’App Router »).

Le coupable habituel : les tâches longues

Toute tâche JavaScript de plus de 50 ms bloque le thread principal. Si l’utilisateur clique pendant ce temps, le navigateur ne peut ni traiter l’événement ni repeindre l’écran.

async function processItems(items) {
    for (const item of items) {
        process(item);
        // Yield to the browser between two items
        await scheduler.yield();
    }
}

Les trois phases d’une interaction

  • Le délai d’entrée : le temps pendant lequel l’événement attend que le thread principal se libère, souvent à cause d’une autre tâche en cours.
  • Le temps de traitement : la durée d’exécution des gestionnaires d’événements eux-mêmes.
  • Le délai de présentation : le calcul des styles, de la mise en page et de l’affichage de la nouvelle image à l’écran.

Savoir quelle phase domine évite d’optimiser au mauvais endroit : un gestionnaire de clic très rapide ne sert à rien si le navigateur met ensuite 300 ms à recalculer la mise en page d’un DOM gigantesque.

Mesurer sur le terrain

Les outils de laboratoire ne cliquent pas comme de vrais visiteurs. La version attribution de la librairie web-vitals aide à comprendre. Pour chaque mesure, elle indique l’élément concerné et la durée de chaque phase :

import { onINP } from 'web-vitals/attribution';

onINP(({ value, attribution }) => {
    sendToAnalytics({
        inp: value,
        target: attribution.interactionTarget,
        inputDelay: attribution.inputDelay,
        processingDuration: attribution.processingDuration,
        presentationDelay: attribution.presentationDelay,
    });
});

Rendre la main sur tous les navigateurs

scheduler.yield() n’est pas encore disponible partout. Une petite fonction permet de l’utiliser quand il existe, et de se rabattre sur setTimeout sinon :

function yieldToMain() {
    if (globalThis.scheduler?.yield) {
        return scheduler.yield();
    }
    return new Promise(resolve => setTimeout(resolve, 0));
}

Réduire le délai de présentation

Un DOM de plusieurs milliers de nœuds rend chaque mise à jour coûteuse. La propriété CSS content-visibility: auto permet au navigateur d’ignorer le rendu des sections hors de l’écran. Il faut aussi éviter de lire une dimension, comme offsetHeight, juste après avoir modifié un style : cela force un calcul de mise en page synchrone.

Les points à vérifier

  • Afficher un retour visuel immédiat, puis faire le travail lourd ensuite.
  • Découper les boucles longues avec scheduler.yield().
  • Utiliser startTransition en React pour les mises à jour non urgentes, et envoyer moins de JavaScript grâce aux Server Components (voir « React Server Components : ce qui change vraiment »).
  • Déporter les calculs lourds dans un Web Worker.
  • En Angular, limiter la détection de changements grâce aux signals et au mode zoneless (voir « Angular Signals : vers un Angular sans Zone.js »).
  • Faire les mesures chez de vrais visiteurs. Outils : web-vitals ou Vercel Speed Insights.

L’INP est un indicateur exigeant parce qu’il reflète l’expérience réelle. Le bon réflexe : ne jamais laisser le thread principal occupé plus de quelques dizaines de millisecondes d’affilée.

Sur le même sujet

  • Next.js
  • SEO
  • React

Next.js : soigner son SEO avec l’App Router

Métadonnées, Open Graph, sitemap, JSON-LD et images de partage : ce que l’App Router de Next.js permet de configurer pour le SEO, et ses pièges.

· 7 min de lecture

  • React
  • Next.js
  • Performance

React Server Components : ce qui change vraiment

Les Server Components ne sont pas du SSR rebaptisé. Tour d’horizon de ce qu’ils apportent, de leurs limites et de la frontière client/serveur.

· 8 min de lecture