L’INP (Interaction to Next Paint) est devenu la métrique Core Web Vital la plus difficile à optimiser sur les sites React et Vue qui dominent les stacks front-end modernes. Contrairement au LCP qui dépend principalement du serveur et du réseau, l’INP mesure la responsivité du JavaScript côté client, et les frameworks SPA accumulent précisément des handlers d’événements lourds et des re-renders coûteux. Pourtant, obtenir un INP sous le seuil « bon » (200 ms) sur ces frameworks ne requiert généralement pas une refonte complète : des optimisations ciblées sur les goulots d’étranglement identifiés transforment la métrique en quelques semaines. Cet article détaille la méthodologie et les patterns éprouvés pour 2026. TBT vs INP : comprendre la différence et prioriser les optimisations JavaScript
À retenir en 30 secondes : identifier les 3 à 5 interactions les plus coûteuses via le Performance panel de Chrome DevTools, puis appliquer les optimisations ciblées : scheduler.yield pour fragmenter les tâches longues, startTransition pour les updates non urgents, memo/useMemo/useCallback pour éviter les re-renders inutiles, virtual scrolling pour les grandes listes, et code splitting pour alléger le bundle initial. Ces techniques ne requièrent pas de refonte, mais une discipline d’optimisation ciblée.
Diagnostiquer : identifier les 3-5 interactions les plus lentes
Avant toute optimisation, identifier les interactions responsables. Chrome DevTools Performance panel enregistre les 10 interactions les plus longues sur une session, avec le détail des tâches JavaScript, re-renders React et paint. L’INP d’une page est dominé par ses pires interactions : si vous optimisez un filtre de catalogue qui prend 500 ms de blocking time, vous gagnez souvent 300 ms sur l’INP mesuré. En règle générale, 3 à 5 interactions identifiées et corrigées suffisent à faire basculer un site de 400 ms d’INP à sous 200 ms. Cette discipline est à rapprocher de notre guide d’ensemble sur le INP et son impact sur le classement Google.
scheduler.yield : fragmenter les tâches longues
Toute tâche JavaScript qui bloque le thread principal plus de 50 ms dégrade l’INP de l’interaction suivante. L’API scheduler.yield() (disponible dans tous les navigateurs modernes depuis fin 2024) permet de céder le contrôle au navigateur entre deux étapes d’un traitement long. Dans un composant React qui doit traiter 1 000 éléments d’une liste, découper le traitement en chunks de 100 et appeler scheduler.yield() entre chaque chunk libère le navigateur pour peindre les interactions utilisateur. L’implémentation tient en 5 lignes de code. Avant scheduler.yield(), on utilisait setTimeout(fn, 0) ou requestIdleCallback — toujours valides mais moins précis sur le contrôle de priorité.
startTransition (React 18+) et computed async (Vue 3+)
React 18 a introduit startTransition pour marquer certaines mises à jour d’état comme non urgentes, permettant au navigateur de prioriser la responsivité des interactions utilisateur. Un filtre de recherche qui déclenche un re-render coûteux de la liste de résultats gagne spectaculairement en INP si l’update de la liste est enveloppé dans startTransition. Vue 3 propose un pattern équivalent via computed async et Suspense. Dans les deux cas, le changement de code est marginal (quelques lignes) et l’impact INP peut être massif. La règle : tout update d’état qui ne nécessite pas un rendu immédiat (recherche en temps réel, filtre de liste) devrait être une transition.
Éviter les re-renders inutiles : memo, useMemo, useCallback
Un composant React qui re-rend ses enfants à chaque update, alors que leurs props n’ont pas changé, dégrade l’INP de manière invisible. React.memo, useMemo pour les valeurs calculées, useCallback pour les fonctions passées en props empêchent ces re-renders inutiles. L’instrumentation via React DevTools Profiler identifie les composants qui re-render trop souvent. Attention à ne pas sur-mémoriser : chaque useMemo ajoute un coût de comparaison. Appliquer stratégiquement aux composants qui apparaissent dans le flame graph de l’INP, pas de manière systématique. Vue 3 avec computed et son système de réactivité fine granulaire gère cela de manière plus automatique mais souffre également des re-renders inutiles sur les composants mal optimisés.
Virtual scrolling et code splitting pour les gros écrans
Les listes de centaines ou milliers d’éléments (catalogues, feeds, tables de données) sont une source classique de mauvais INP. Le virtual scrolling (via react-window, @tanstack/react-virtual, vue-virtual-scroller) rend uniquement les éléments visibles, divisant le DOM par 10 à 100. Le code splitting via les API de chargement dynamique de React (lazy, Suspense) ou de Vue (defineAsyncComponent) réduit le bundle initial, améliore le TBT (Total Blocking Time) et donc l’INP sur les premières interactions. Ces deux techniques requièrent un travail d’intégration plus substantiel que scheduler.yield() mais produisent des gains durables sur les écrans à forte volumétrie. Pour prolonger la réflexion sur l’optimisation web vitals en général, consultez notre guide Core Web Vitals complet.
Pour l’approfondissement technique de l’optimisation INP sur les frameworks modernes, la documentation officielle web.dev sur l’optimisation de l’INP couvre les patterns avancés et les benchmarks.
Mon point de vue d’expert
En audit de sites React et Vue, l’INP est systématiquement la métrique où je trouve le plus de gains possibles, et aussi celle que les équipes croient à tort inoptimisable sans refonte. Erreur : les 5 techniques ci-dessus permettent typiquement de diviser l’INP par 2 à 3 sans toucher à l’architecture globale. Mon conseil pour les équipes et agences : commencez par un diagnostic ciblé des interactions les plus lentes via Chrome DevTools, appliquez scheduler.yield() et startTransition sur les 3 pires cas identifiés, mesurez l’impact. Dans 80 % des cas, cela suffit pour passer sous le seuil 200 ms. Pour les 20 % restants, le virtual scrolling et le code splitting règlent les cas plus structurels. L’investissement est faible, l’impact SEO et UX est substantiel. L’erreur classique est de reporter l’optimisation INP en attendant une refonte hypothétique — pendant ce temps, les positions se dégradent.
FAQ : optimiser l’INP sur React et Vue
- Quel seuil INP viser pour un bon score Core Web Vitals ?
- Le seuil « bon » est 200 ms (p75). Le seuil « à améliorer » est entre 200 et 500 ms. Au-delà de 500 ms, l’INP est considéré « mauvais » et pénalise directement. Viser 150 ms pour disposer d’une marge confortable face aux variations de hardware utilisateur.
- Server-Side Rendering (SSR) améliore-t-il l’INP ?
- Indirectement, oui. Un SSR correctement implémenté réduit le temps avant interactivité, et donc le hydration time qui est souvent le pire INP mesuré sur les SPA. Mais le SSR ne règle pas les problèmes d’interactivité ultérieure. L’optimisation INP post-hydration reste nécessaire quel que soit le rendu initial.
- Les Web Workers aident-ils à optimiser l’INP ?
- Oui, pour les calculs lourds qui peuvent être délégués hors du thread principal (traitement d’images, parsing de gros JSON, calculs analytiques). Mais l’overhead de communication est non négligeable, et les Workers ne peuvent pas accéder au DOM. À utiliser stratégiquement sur les cas où le gain compense l’overhead.
- Comment mesurer l’INP en production vs laboratoire ?
- En laboratoire via Lighthouse et PageSpeed Insights (simulation). En production via CrUX / Search Console (données réelles sur votre audience) ou via une solution RUM (Real User Monitoring) comme SpeedCurve, DebugBear, ou web-vitals.js intégré à votre analytics. Les deux sources sont complémentaires : laboratoire pour détecter les causes, production pour mesurer l’impact réel.



