Délai d'entrée de l'INP : causes, diagnostic et correctifs
Apprenez à identifier et corriger les problèmes d'INP causés par les délais d'entrée.
Problèmes d'Interaction to Next Paint (INP) causés par le délai d'entrée
Cette page fait partie de notre série sur l'Interaction to Next Paint (INP). L'INP mesure le temps total entre une interaction utilisateur et la prochaine mise à jour visuelle. Le délai d'entrée est la première des trois phases de l'INP. Il est suivi par le temps de traitement et le délai de présentation. Si vous découvrez l'INP, lisez d'abord notre guide pour identifier et corriger les problèmes d'INP.
ASTUCE INP : le délai d'entrée se produit généralement au début du chargement de la page. C'est le moment où le navigateur est le plus occupé à analyser et exécuter les scripts.
Table of Contents!
- Problèmes d'Interaction to Next Paint (INP) causés par le délai d'entrée
- Qu'est-ce que le délai d'entrée ?
- Le délai d'entrée et l'INP
- L'importance du délai d'entrée
- Causes du délai d'entrée
- Minimiser le délai d'entrée
- Découper les tâches avec scheduler.yield()
- Prioriser les tâches avec scheduler.postTask()
- Implications pratiques
- Explorer les autres phases de l'INP
Qu'est-ce que le délai d'entrée ?

Le délai d'entrée désigne le temps nécessaire au navigateur pour commencer à traiter un callback d'événement après une interaction utilisateur avec la page (par exemple, cliquer sur un bouton ou appuyer sur une touche). Il y a toujours un léger délai d'entrée (même les navigateurs ont besoin de temps pour planifier les callbacks). Un délai d'entrée excessif survient quand le navigateur est occupé par d'autres tâches planifiées. Il ne peut pas planifier immédiatement les callbacks demandés par l'interaction.
Pendant le délai d'entrée, l'utilisateur a déjà effectué son action (clic, tap ou pression de touche). Le navigateur n'a pas encore commencé à exécuter le gestionnaire d'événements associé. L'utilisateur ne voit aucune réponse. C'est différent du temps de traitement, où le gestionnaire d'événements s'exécute activement. C'est aussi différent du délai de présentation, où le navigateur fait le rendu de la mise à jour visuelle. Le délai d'entrée est un pur temps d'attente causé par un main thread congestionné.
Le délai d'entrée et l'INP
L 'Interaction to Next Paint (INP) se divise en 3 parties : « Délai d'entrée », « Temps de traitement » et « Délai de présentation ».

Vous remarquerez une similitude de nom entre le délai d'entrée et l'ancien Core Web Vital « First Input Delay » (FID). L'Interaction to Next Paint a remplacé le FID comme Core Web Vital en mars 2024. Le First Input Delay mesurait uniquement le temps entre la première interaction et le callback de l'événement. Le FID est abandonné, mais le délai d'entrée reste important. Il est à la base de chaque mesure d'Interaction to Next Paint.
L'importance du délai d'entrée
Beaucoup de développeurs pensent à améliorer l'INP en optimisant les fonctions de callback (optimiser le temps de traitement). Le délai d'entrée est donc souvent négligé. Le délai d'entrée n'est généralement pas la plus grande partie de l'INP. Cependant, optimiser le délai d'entrée optimise souvent toutes les interactions INP en même temps. Réduire le délai d'entrée améliore chaque interaction sur la page, pas seulement la pire.

Chez CoreDash, nous collectons des millions de points de données Core Web Vitals chaque heure. Selon ces données, le délai d'entrée représente environ 18 % de l'Interaction to Next Paint. C'est moins que le temps de traitement ou le délai de présentation. Le délai d'entrée est cependant souvent la phase la plus facile à réduire. La cause fondamentale est presque toujours « trop de JavaScript exécuté au mauvais moment ».
Causes du délai d'entrée
Le délai d'entrée survient quand le main thread est occupé à exécuter d'autres tâches. Ces tâches peuvent provenir de :

- Tâches initiales. Les scripts normaux, avec defer et async mis en file d'attente tôt créent des tâches initiales. C'est la source la plus courante de délai d'entrée. Ils s'exécutent pendant la fenêtre critique de démarrage, quand les utilisateurs sont les plus susceptibles d'interagir avec la page.
- Tâches planifiées. Certaines tâches ne s'exécutent pas au début du chargement de la page. Elles peuvent être planifiées pour après le chargement de la page. Ces tâches peuvent aussi interférer avec l'INP et causer un délai d'entrée. Par exemple, les scripts qui s'exécutent après l'événement
window.onloadou les scripts retardés par de prétendus plugins d'optimisation. Découvrez quand utiliser async ou defer pour JavaScript. - Tâches répétitives. Les tâches récurrentes via
setInterval()qui prennent beaucoup de temps à s'exécuter et se produisent en même temps que l'INP. - Callbacks chevauchants. Les callbacks chevauchants sont une cause fréquente de délai d'entrée. Plusieurs callbacks planifiés de manière rapprochée créent une file d'attente. Cela retarde le traitement de l'interaction suivante. Par exemple, un gestionnaire
mouseoverdéclenché juste avant un gestionnaireclickpeut repousser le traitement du clic de la durée de la tâche du mouseover.
Minimiser le délai d'entrée
- Découper les long tasks initiales en plusieurs tâches plus petites. Pendant les long tasks, le navigateur ne peut pas répondre aux entrées de l'utilisateur. Après chaque tâche courte, le navigateur peut y répondre. Découpez les long tasks avec
scheduler.yield(). Vous pouvez aussi envelopper chaque fonction dans un timeout de 0 avecsetTimeout(callback, 0). - Gérer les éléments interactifs. Ne présentez pas d'éléments interactifs (comme une barre de recherche) avant le chargement complet du JavaScript qui les contrôle. Cela empêche les clics prématurés sur des éléments non prêts à les recevoir. Pour optimiser l'UX sur ce point, priorisez le chargement du JavaScript nécessaire. Vous pouvez aussi masquer ou désactiver temporairement l'élément jusqu'à ce qu'il soit fonctionnel.
- Exécution de scripts pendant le temps inactif. Planifiez l'exécution des scripts non critiques pendant les périodes d'inactivité du navigateur avec
requestIdleCallback(). Cette fonction s'exécute quand le navigateur est inactif et n'a pas besoin de traiter d'entrées utilisateur. - Utiliser des web workers pour exécuter le JavaScript en dehors du main thread du navigateur. Les web workers permettent d'exécuter des scripts en dehors du main thread. Cela empêche le main thread de bloquer et de causer des problèmes de délai d'entrée sur l'INP.
- Vérifier les entrées en attente pendant les tâches répétitives. Avant d'exécuter un ensemble de tâches planifiées, vérifiez les entrées en attente. S'il y a une entrée en attente, faites un yield vers le main thread en premier.
- Supprimer le code inutile. Auditez régulièrement vos scripts. Supprimez le code inutile, voire des scripts entiers. Chaque ligne de code peut causer un délai d'entrée qui affecte l'Interaction to Next Paint. Consultez notre guide sur 14 méthodes pour différer le JavaScript pour des techniques pratiques.
Découper les tâches avec scheduler.yield()
L'API scheduler.yield() est la méthode recommandée pour découper les long tasks. Contrairement à setTimeout(callback, 0), qui place la suite à la fin de la file d'attente des tâches, scheduler.yield() préserve la priorité de la tâche. Le navigateur reprendra votre code dès que possible après avoir traité toute entrée utilisateur en attente. Voici une fonction utilitaire réutilisable :
async function yieldToMain() {
if ('scheduler' in window && 'yield' in window.scheduler) {
return await window.scheduler.yield();
}
// Fallback pour les navigateurs sans scheduler.yield()
return new Promise((resolve) => {
setTimeout(resolve, 0);
});
}
// Exemple : découper une longue séquence d'initialisation
async function initializeApp() {
loadCriticalFeatures();
await yieldToMain(); // Laisser le navigateur traiter toute entrée en attente
loadSecondaryFeatures();
await yieldToMain();
loadAnalytics();
await yieldToMain();
loadNonEssentialWidgets();
} Pour en savoir plus sur le fonctionnement interne de scheduler.yield(), consultez le blog Chrome Developers.
Prioriser les tâches avec scheduler.postTask()
Alors que scheduler.yield() découpe les tâches, scheduler.postTask() vous donne un contrôle précis sur la priorité des tâches. L'API accepte trois niveaux de priorité : "user-blocking" pour les tâches critiques nécessitant la plus haute priorité, "user-visible" pour les tâches de priorité moyenne, et "background" pour les tâches de priorité la plus basse qui doivent s'exécuter pendant le temps d'inactivité.
En utilisant postTask(), vous vous assurez que le travail non essentiel ne bloque pas les interactions utilisateur. Voici un exemple pratique qui planifie le travail d'analytique avec une priorité background. Il garde les mises à jour de l'interface utilisateur avec la plus haute priorité :
// Haute priorité : le retour de l'interface utilisateur s'exécute en premier
scheduler.postTask(() => {
showLoadingSpinner();
}, { priority: 'user-blocking' });
// Priorité moyenne : récupérer les données
scheduler.postTask(async () => {
const data = await fetchSearchResults(query);
renderResults(data);
}, { priority: 'user-visible' });
// Basse priorité : l'analytique peut attendre
scheduler.postTask(() => {
trackSearchEvent(query);
sendToAnalytics('search', { query });
}, { priority: 'background' }); Vérifiez le tableau de support des navigateurs pour scheduler.postTask() avant de l'utiliser en production. Pour les navigateurs qui ne supportent pas l'API, utilisez requestIdleCallback() comme fallback pour les tâches en arrière-plan et queueMicrotask() pour les tâches à haute priorité.
Implications pratiques
Qu'est-ce que cela signifie pour votre site ? Voici des recommandations spécifiques pour WordPress et React/Next.js.
WordPress
En raison de son architecture basée sur les plugins, WordPress inclut souvent un thème et de nombreux plugins. Les plugins et les thèmes dépendent fréquemment du JavaScript pour leurs fonctionnalités. Comme ces plugins et thèmes sont maintenus par des développeurs tiers, vous n'avez aucun contrôle sur leur contenu. Vous ne pouvez pas modifier les fichiers et optimiser le « mauvais code ». Même si les scripts se comportent bien aujourd'hui, rien ne garantit qu'ils le feront après la prochaine mise à jour.
Pour minimiser le délai d'entrée et optimiser l'Interaction to Next Paint (INP) sur WordPress, suivez ces étapes :
- Évitez d'utiliser des plugins quand c'est possible. Les plugins sont un moyen facile d'ajouter des fonctionnalités. Cependant, ils ajoutent souvent des scripts à la page. Ces scripts causeront un délai d'entrée qui impacte l'INP. Pour chaque plugin, posez-vous la question : puis-je obtenir la même fonctionnalité avec du code sur mesure ou une solution côté serveur ?
- Choisissez des thèmes légers. Beaucoup de thèmes WordPress « offrent tout ». Cela semble être une bonne idée, mais ils sont probablement remplis de fonctionnalités inutilisées. Celles-ci consomment du temps CPU précieux.
- Évitez les page builders. Les page builders comme Elementor ou WPBakery offrent une interface visuelle conviviale pour créer des mises en page. Malheureusement, ils dépendent souvent de scripts lourds pour présenter cette mise en page aux visiteurs.
- Chargez les scripts uniquement quand ils sont nécessaires. WordPress a tendance à charger tous les scripts sur toutes les pages. Pour corriger cela, créez un thème enfant et désenregistrez les scripts inutiles par type de page :
function my_deregister_scripts() {
if ( ! is_page( 'contact' ) ) {
// Désenregistrer le script du formulaire de contact sur les pages autres que contact
wp_dequeue_script( 'contact-form-script' );
}
}
add_action( 'wp_enqueue_scripts', 'my_deregister_scripts' ); - Auditez votre Tag Manager. Les conteneurs Google Tag Manager accumulent souvent des balises avec le temps. Chaque balise déclenchée pendant le chargement de la page ajoute une tâche au main thread. Supprimez les balises inutilisées. Définissez des déclencheurs appropriés (par exemple, déclenchez les balises marketing uniquement sur les pages de conversion). Utilisez les rapports de temps intégrés du Tag Manager pour identifier les balises lentes.
- Retardez les scripts tiers non essentiels. Les widgets de chat, les outils de feedback et les intégrations de réseaux sociaux n'ont pas besoin de se charger immédiatement. Utilisez
requestIdleCallback()ou un déclencheur basé sur le scroll pour les charger uniquement quand l'utilisateur est susceptible d'en avoir besoin. Pour des stratégies détaillées, lisez notre guide sur 14 méthodes pour différer le JavaScript.
React / Next.js
Les sites React et Next.js sont principalement propulsés par JavaScript. Exécuter les scripts de démarrage, hydrater les composants et traiter le DOM virtuel prennent du temps. Cela peut causer un délai d'entrée pour l'Interaction to Next Paint (INP). La bonne nouvelle est que React et Next.js fournissent tous deux des outils pour gérer cela efficacement.
- Utilisez les composants serveur (React Server Components dans le Next.js App Router). Les composants serveur sont rendus sur le serveur. Ils n'envoient aucun JavaScript au client. Cela réduit directement la quantité de code en concurrence pour le temps du main thread.
- Chargez les scripts tiers avec la bonne stratégie. Dans Next.js, utilisez le composant
next/scriptavecstrategy="afterInteractive"pour les scripts nécessaires après l'hydratation. Utilisezstrategy="lazyOnload"pour les scripts qui peuvent se charger pendant le temps inactif du navigateur. Consultez notre guide async ou defer pour JavaScript pour les principes sous-jacents. - Implémentez un pattern idle-until-urgent. Ce pattern priorise les interactions utilisateur sur les tâches en arrière-plan. Il utilise
requestIdleCallback()pour l'initialisation non critique tout en gardant un fallback synchrone. Ce dernier s'active quand le composant est réellement nécessaire. - Faites du lazy loading sur les composants. Appliquez le lazy loading aux composants qui ne sont pas immédiatement nécessaires avec
React.lazy()ou ledynamic()de Next.js avec{ ssr: false }pour les composants purement client. - Utilisez Suspense pour les composants interactifs. Enveloppez les composants interactifs dans des frontières
<Suspense>. Ainsi, le reste de la page peut faire son rendu et devenir interactif pendant que les composants lourds se chargent en arrière-plan. Cela empêche un composant lent unique de bloquer le traitement des entrées sur toute la page. - Utilisez les transitions React pour les mises à jour non urgentes. Enveloppez les mises à jour d'état non critiques dans
startTransition(). React peut ainsi les interrompre si l'utilisateur effectue une nouvelle interaction. Cela garde l'interface utilisateur réactive même quand de gros re-rendus sont en cours.
Explorer les autres phases de l'INP
Pour maîtriser votre INP, traitez également les deux autres phases :
- Temps de traitement : Optimisez le code du gestionnaire d'événements qui s'exécute pendant l'interaction. Sur la plupart des pages, c'est là que l'essentiel de vos efforts d'optimisation porte ses fruits.
- Délai de présentation : Réduisez le travail de rendu et de peinture qui suit le traitement des événements. Sur les pages complexes avec de grands DOM, c'est souvent la phase la plus longue.
Pour un workflow de diagnostic complet, consultez notre guide pour trouver et corriger les problèmes d'INP. Retournez sur la page d'accueil INP pour une vue d'ensemble complète.
Votre score Lighthouse ne dit pas tout.
Vos vrais utilisateurs sont sur Android en 4G. Moi, j'analyse ce qu'ils vivent réellement.
Analyser les données terrain