Optimiser le First Input Delay

Comment réagir plus rapidement aux interactions des utilisateurs

J'ai cliqué, mais rien ne s'est passé. Pourquoi ne puis-je pas interagir avec cette page ? 😢

First Contentful Paint (FCP) et Largest Contentful La peinture (LCP) est deux métriques qui mesurent le temps nécessaire pour que le contenu s'affichent (repeindre) visuellement sur une page. Bien qu'important, les délais de peinture ne tiennent pas compte de la charge la réactivité, c'est-à-dire la rapidité avec laquelle une page répond aux interactions des utilisateurs.

First Input Delay (FID) est une métrique Core Web Vitals qui capture le première impression de l'interactivité et de la réactivité d'un site. Il mesure le délai entre le moment où un utilisateur interagit d'abord avec une page jusqu'au moment où le navigateur est en mesure de réagir d'interaction. Le FID est une métrique de champ et ne peut pas être simulées dans un environnement de laboratoire. Une interaction réelle de l'utilisateur est nécessaire pour mesurer la le délai de réponse.

Les bonnes valeurs fid sont de 2,5 secondes, les valeurs médiocres supérieures à 4 secondes et toute valeur intermédiaires doit être améliorée.

Pour vous aider à prédire le FID dans l'atelier, nous nous recommandons d'utiliser Total Blocking Time (TBT). Ils mesurent différentes choses, mais d’amélioration de la précision des données correspondent généralement à des améliorations du FID.

Une exécution intensive de JavaScript est la cause principale d'un FID médiocre. Optimiser l'analyse par JavaScript se compile et s'exécute sur votre page Web, réduit directement le FID.

Exécution intensive de JavaScript

Le navigateur ne peut pas répondre à la plupart des entrées utilisateur lorsqu'il exécute JavaScript sur le thread principal. En d'autres termes, le navigateur ne peut pas répondre aux interactions des utilisateurs lorsque le thread principal est occupé. Pour améliorer cela:

Décomposer les longues tâches

Si vous avez déjà essayé de réduire la quantité de code JavaScript chargé sur une seule page, vous pouvez être utile pour décomposer le code de longue durée en tâches asynchrones plus petites.

Les tâches longues sont des périodes d'exécution JavaScript pendant lesquelles les utilisateurs peuvent votre interface utilisateur ne répond plus. Tout élément de code qui bloque le thread principal pendant 50 ms ou plus peut être caractérisé par une longue tâche. Les longues tâches sont le signe une surcharge JavaScript potentielle (chargement et exécution d'une quantité supérieure à celle dont un utilisateur peut avoir besoin en ce moment) ; Le fractionnement des longues tâches peut réduire le délai de saisie sur votre site.

Tâches longues dans les outils pour les développeurs Chrome
Les outils pour les développeurs Chrome visualisent les longues tâches dans le panneau "Performances"

Le FID devrait s'améliorer considérablement à mesure que vous adoptez des bonnes pratiques telles que la division du code et la séparation Longues tâches. Bien que le ciblage par niveau d'appareil ne soit pas une métrique de terrain, il est utile pour vérifier la progression vers ce qui améliore à la fois le délai d'interaction (TTI) et le FID.

Optimiser votre page pour préparer les interactions

Il existe un certain nombre de causes courantes de faibles scores FID et TTC dans les applications Web qui s'appuient fortement sur JavaScript:

L'exécution du script propriétaire peut retarder la préparation aux interactions

  • L'augmentation de la taille du code JavaScript, les temps d'exécution importants et la fragmentation inefficace peuvent ralentir le délai d'affichage peut répondre aux entrées de l'utilisateur et avoir un impact sur le FID, le TTI et le TTI. Le chargement progressif du code et peuvent vous aider à étaler ce travail et à améliorer votre aptitude à interagir.
  • Les applications affichées côté serveur peuvent avoir l'impression que des pixels sont peints à l'écran. rapidement, mais méfiez-vous si les interactions des utilisateurs sont bloquées par des exécutions de scripts volumineux (par exemple, la réhydratation pour connecter les écouteurs d'événements). Cette opération peut prendre plusieurs centaines de millisecondes, voire quelques secondes, si la division du code basée sur l'itinéraire est utilisée. Envisagez de changer de logique côté serveur ou de générer plus de contenu de manière statique pendant la compilation.

Vous trouverez ci-dessous les scores de TSA avant et après l'optimisation du chargement du script propriétaire pour une application. En supprimant le chargement (et l'exécution) d'un script coûteux pour un composant non essentiel chemin critique, les utilisateurs ont pu interagir avec la page beaucoup plus tôt.

Améliorations du score TBT dans Lighthouse après l'optimisation du script propriétaire.

L'extraction des données peut avoir un impact sur de nombreux aspects de la préparation aux interactions

  • En attente d'une cascade d'extractions en cascade (par exemple, JavaScript et les extractions de données pour les composants) peut impacter la latence des interactions. Essayez de limiter au maximum la dépendance aux extractions de données en cascade.
  • Les datastores intégrés volumineux peuvent augmenter la durée d'analyse HTML et avoir un impact sur la peinture et l'interaction. métriques. Essayez de minimiser la quantité de données à post-traiter côté client.

L'exécution de scripts tiers peut également retarder la latence des interactions

  • De nombreux sites incluent des balises et des outils d'analyse tiers, ce qui peut occuper le réseau et qui empêchent régulièrement le thread principal de répondre, ce qui a un impact sur la latence des interactions. Explorer le chargement à la demande de code tiers (par exemple, ne chargez pas les annonces situées en dessous de la ligne de flottaison tant que lorsque l'utilisateur fait défiler l'écran et se rapproche de la fenêtre d'affichage).
  • Dans certains cas, les scripts tiers peuvent devancer les scripts propriétaires en termes de priorité et de la bande passante sur le thread principal, ce qui retarde également le délai entre une page prête pour l'interaction. Essayez de Privilégiez d'abord ce qui, selon vous, offre la plus grande valeur ajoutée aux utilisateurs.

Utiliser un nœud de calcul Web

Le blocage d'un thread principal est l'une des causes principales du retard d'entrée. Web des nœuds de calcul permettent d'exécuter du code JavaScript sur un thread d'arrière-plan. Le déplacement d'opérations autres que celles liées à l'UI vers un thread de nœud de calcul distinct peut réduire de blocage des threads et améliore ainsi le FID.

Pensez à utiliser les bibliothèques suivantes pour faciliter l'utilisation des workers Web sur votre site:

  • Comlink: bibliothèque d'aide qui extrait postMessage et facilite son utilisation
  • Workway: exportateur de nœuds de calcul Web à usage général
  • Workerize (Utiliser des nœuds de calcul) : déplacer un module vers un nœud de calcul Web

Réduire le temps d'exécution de JavaScript

Limiter la quantité de JavaScript sur votre page permet de réduire le temps nécessaire au navigateur pour l'exécution de code JavaScript. Le navigateur peut ainsi répondre plus vite à toute les interactions des utilisateurs.

Pour réduire le nombre d'exécutions de code JavaScript sur votre page:

  • Reporter le code JavaScript inutilisé
  • Réduire les polyfills inutilisés

Reporter le code JavaScript inutilisé

Par défaut, tout JavaScript bloque l'affichage. Lorsque le navigateur rencontre un tag de script qui renvoie vers un fichier JavaScript externe, il doit interrompre son travail et télécharger, analyser, compiler et exécuter que JavaScript. Vous ne devez donc charger que le code nécessaire à la page ou pour répondre à l'entrée utilisateur.

Onglet Couverture dans Chrome Les outils de développement peuvent vous indiquer la quantité de code JavaScript qui n'est pas utilisé sur votre page Web.

Onglet "Couverture"

Pour réduire la quantité de code JavaScript inutilisé:

  • Divisez votre bundle en plusieurs fragments de code
  • Différez tout code JavaScript non critique, y compris les scripts tiers, à l'aide de async ou defer.

La répartition du code est le concept qui consiste à diviser un seul groupe JavaScript volumineux en fragments plus petits. qui peut être chargé de manière conditionnelle (également appelé chargement différé). La plupart des navigateurs récents sont compatibles avec la syntaxe d'importation dynamique. qui permet d'extraire des modules à la demande:

import('module.js').then((module) => {
  // Do something with the module.
});

L'importation dynamique de code JavaScript pour certaines interactions utilisateur (par exemple, la modification d'un itinéraire ou l'affichage d'une modale) garantit que le code non utilisé pour le chargement initial de la page n'est récupéré que lorsque nécessaires.

Outre la compatibilité générale avec les navigateurs, la syntaxe d'importation dynamique peut être utilisée dans de nombreux types de compilations différents. systèmes.

  • Si vous utilisez webpack, Vue d'ensemble, ou Parcel en tant que bundler de modules, profitez des leur compatibilité avec l'importation dynamique.
  • Les frameworks côté client, comme React Angular Vue apporte pour faciliter le chargement différé au niveau du composant.

Hormis la division du code, utilisez toujours les requêtes async ou "defer" pour les scripts qui ne sont pas nécessaires le chemin critique ou le contenu au-dessus de la ligne de flottaison.

<script defer src="…"></script>
<script async src="…"></script>

Sauf s'il y a une raison spécifique, tous les scripts tiers doivent être chargés avec defer ou async par défaut.

Réduire les polyfills inutilisés

Si vous créez votre code en utilisant la syntaxe JavaScript moderne et référencez les API des navigateurs modernes, vous allez vous devez le transpiler et inclure des polyfills pour qu'il fonctionne dans les navigateurs plus anciens.

L'un des principaux problèmes de performances liés à l'intégration de polyfills et de code transcompilé dans votre site est que les navigateurs plus récents ne devraient pas avoir à le télécharger s’ils n’en ont pas besoin. Pour réduire le JavaScript de votre application, réduisez autant que possible les polyfills inutilisés et limitez leur utilisation à dans les environnements où elles sont nécessaires.

Pour optimiser l'utilisation des polyfills sur votre site:

  • Si vous vous servez de Babel comme transcompilateur, utilisez @babel/preset-env pour n'inclure que les polyfills nécessaires pour les navigateurs que vous prévoyez de cibler. Pour Babel 7.9, activez le l'option bugfixes pour réduire davantage sur les polyfills inutiles
  • Utilisez le modèle module/nomodule pour fournir deux lots distincts (@babel/preset-env également prend en charge cette opération via target.esmodules.)

    <script type="module" src="modern.js"></script>
    <script nomodule src="legacy.js" defer></script>
    

    De nombreuses nouvelles fonctionnalités ECMAScript compilées avec Babel sont déjà prises en charge dans les environnements compatibles avec les modules JavaScript. Ainsi, vous simplifiez le processus pour vous assurer que seul le code transcompilé est utilisé pour les navigateurs qui en ont réellement besoin.

Outils pour les développeurs

Plusieurs outils sont disponibles pour mesurer et déboguer le FID:

  • Lighthouse 6.0 n'inclut pas la prise en charge du FID, car il s’agit d’une métrique de champ. Toutefois, Total Blocking Time (TBT) peut être utilisé comme proxy. Les optimisations qui améliorent le ciblage par types d'appareil doivent améliorent également le FID sur le terrain.

    Lighthouse 6.0.

  • Rapport sur l'expérience utilisateur Chrome fournit des valeurs FID réelles, agrégées au niveau de l'origine

Merci à Philip Walton, Kayce Basque, Ilya Grigorik et Annie Sullivan pour leurs commentaires.