Comment rendre la main au thread principal pour améliorer l'INP
Utilisez scheduler.yield() pour fractionner les tâches longues et maintenir la réactivité de vos pages

Rendre la main au thread principal
Imaginez un film romantique. Le décor est un petit marché français au centre d'un petit village. Les rues sont remplies de couples buvant du café, mangeant des croissants et achetant des fleurs. Imaginez maintenant ce qui se passe si un seul acheteur peut effectuer un achat auprès d'un vendeur à la fois, tandis que tous les autres doivent attendre leur tour. Le boulanger est submergé de demandes, des disputes éclatent chez le fleuriste et la promenade romantique se transforme en une attente frustrante.
Eh bien... c'est un peu ce qui se passe sur un site web lorsque les choses deviennent trop chargées.
Dernière révision par [url=https:\/\/www.linkedin.com\/in\/arjenkarel\/]Arjen Karel[\/url] en mars 2026
Pourquoi rendre la main (yielding) est important pour l'INP
Le thread principal d'un navigateur gère tous les processus importants : l'analyse du HTML et du CSS, l'exécution du JavaScript, la gestion des événements d'entrée comme les clics et les défilements, et le rendu visuel. Il fonctionne sur un modèle mono-thread, ce qui signifie qu'il ne peut effectuer qu'une seule tâche à la fois. Lorsqu'une tâche commence à s'exécuter, le navigateur l'exécute jusqu'à son terme et ne s'arrête pas avant qu'elle ne soit finie. Aucune autre tâche n'est planifiée tant que la tâche actuelle n'est pas terminée. C'est ce qu'on appelle bloquer le thread principal.
Le blocage du thread principal est la cause première des mauvais scores [url=\/core-web-vitals\/interaction-to-next-paint]Interaction to Next Paint (INP)[\/url]. Lorsqu'un visiteur clique sur un bouton et que votre JavaScript bloque le thread principal pendant 200 ms, le navigateur ne peut pas afficher de réponse tant que le script n'est pas terminé. La phase de [url=\/core-web-vitals\/interaction-to-next-paint\/processing-time]processing time[\/url] de l'INP mesure précisément ce délai. Selon le [url=https:\/\/almanac.httparchive.org\/en\/2025\/performance]Web Almanac 2025[\/url], le temps de blocage total (Total Blocking Time) mobile médian est de 1 916 ms, en hausse de 58 % par rapport à l'année précédente. Cela représente près de 2 secondes pendant lesquelles le navigateur ne peut pas répondre aux entrées de l'utilisateur.
Une façon de corriger cela est de rendre la main (yielding) au thread principal. Le yielding est une technique où les tâches longues sont fractionnées en plusieurs tâches plus petites pour permettre au navigateur de gérer des travaux plus importants (comme répondre aux entrées de l'utilisateur) entre elles.
Tâches longues et période de blocage : lorsqu'une tâche prend plus de 50 millisecondes, elle est classée comme une tâche longue, et tout ce qui dépasse ce seuil de 50 millisecondes est appelé "période de blocage" de la tâche. Fractionner ces tâches longues en morceaux plus petits permet au navigateur de rester réactif, même lors de la gestion d'opérations gourmandes en calcul. Anciennes stratégies de yielding
Avant l'[url=https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/API\/Prioritized_Task_Scheduling_API]API Prioritized Task Scheduling[\/url], il existait 4 façons de rendre la main au thread principal. Toutes ont des limites.
- setTimeout() : la stratégie la plus courante.
setTimeout() avec un délai de 0 ajoute la tâche à la fin de la file d'attente, permettant aux autres tâches de s'exécuter en premier. Le problème : les tâches ne peuvent être poussées qu'à la fin de la file d'attente, de sorte que d'autres scripts peuvent passer devant avant que votre code ne reprenne. Les appelssetTimeout() imbriqués imposent également un délai minimum de 5 ms après cinq rounds.- requestAnimationFrame() : place une fonction en file d'attente pour qu'elle s'exécute avant le prochain rafraîchissement (repaint) du navigateur. Souvent combiné avec
setTimeout() pour s'assurer que les rappels (callbacks) sont planifiés après la prochaine mise à jour de la mise en page (layout). Pas conçu pour le yielding, mais pour le travail d'animation.- requestIdleCallback() : mieux adapté aux tâches non critiques et de faible priorité qui peuvent s'exécuter pendant les temps d'arrêt du navigateur. La limite : il n'y a aucune garantie que les tâches planifiées s'exécuteront rapidement (ou même du tout) sur un thread principal occupé.
- isInputPending() : vérifie les entrées utilisateur en attente et ne rend la main que si une entrée est détectée. [url=https:\/\/web.dev\/articles\/optimize-long-tasks]Google ne recommande plus cette approche[\/url]. Elle peut renvoyer des faux négatifs et ne tient pas compte d'autres travaux critiques pour la performance comme les animations et les mises à jour de rendu.
scheduler.yield()
Les limites de ces méthodes ont été une préoccupation pour l'équipe Chrome, d'autant plus que de nombreux sites échouent à l'[url=\/core-web-vitals\/interaction-to-next-paint]INP[\/url]. Pour remédier à cela, ils ont créé
scheduler.yield() : une nouvelle API qui permet aux développeurs de rendre la main au thread principal immédiatement sans réorganiser l'ordre des tâches ni ajouter de complexité.scheduler.yield() a été [url=https:\/\/developer.chrome.com\/blog\/new-in-chrome-129]déployé en version stable dans Chrome 129[\/url] (septembre 2024) et est désormais supporté par tous les principaux navigateurs, à l'exception de Safari.Exemple de code
Puisque Safari ne supporte pas encore
scheduler.yield(), utilisez une solution de repli (fallback) avecsetTimeout() :function yieldToMain() {if ('scheduler' in window && 'yield' in window.scheduler) {return window.scheduler.yield();}return new Promise((resolve) => {setTimeout(resolve, 0);}); } - requestAnimationFrame() : place une fonction en file d'attente pour qu'elle s'exécute avant le prochain rafraîchissement (repaint) du navigateur. Souvent combiné avec