Vers une métrique de fluidité de l'animation

Apprenez à mesurer les animations, à considérer les images d'animation et à gérer la fluidité globale de la page.

Behdad Bakhshinategh
Behdad Bakhshinategh
Jonathan Ross
Jonathan Ross
Michal Mocny
Michal Mocny

Vous avez probablement constaté que certaines pages ou "figer" pendant le défilement ou des animations. Nous tenons à dire que ces expériences ne sont pas fluides. Adresse d'arrivée ce type de problèmes, l'équipe Chrome s'efforce d'ajouter des fonctionnalités à nos outils de l'atelier pour la détection des animations et nous apportons régulièrement des améliorations aux diagnostics du pipeline de rendu dans Chromium.

Nous aimerions faire part de nos progrès récents, vous proposer des conseils concrets sur les outils et discuter d'idées pour de futures métriques de fluidité des animations. Comme toujours, nous serions ravis pour nous faire part de vos commentaires.

Cet article aborde trois thèmes principaux:

  • Présentation rapide des animations et des frames d'animation.
  • Nos réflexions actuelles sur la mesure de la fluidité globale d'une animation.
  • Voici quelques suggestions pratiques à exploiter dans les outils d'atelier dès aujourd'hui.

Que sont les animations ?

Les animations donnent vie à vos contenus ! En faisant bouger le contenu, en particulier en réponse aux interactions avec les utilisateurs, les animations peuvent rendre une expérience plus naturelle, compréhensible et amusante.

Mais une mauvaise mise en œuvre des animations ou l'ajout d'un trop grand nombre d'animations peuvent dégrader l'expérience et la rendre décidément peu amusante. Nous avons probablement tous interagi avec une interface qui venait d'ajouter trop d'éléments « utiles » transition qui deviennent hostiles aux autres en cas de mauvaises performances. Certains utilisateurs pourraient donc préfèrent les mouvements réduits, une préférence de l'utilisateur que vous devez honorer.

Comment fonctionnent les animations ?

En résumé, le pipeline de rendu comporte plusieurs étapes séquentielles:

  1. Style:pour calculer la qui s'appliquent aux éléments.
  2. Layout (Mise en page) : générez la la géométrie et la position de chaque élément.
  3. Paint:remplissez le de pixels de chaque élément en couches.
  4. Composite:dessinez le de calques à l'écran.

Bien qu'il existe de nombreuses façons de définir des animations, elles fonctionnent toutes fondamentalement via l'une des options suivantes:

  • Ajuster la mise en page propriétés.
  • Ajuster la peinture propriétés.
  • Ajuster l'attribut composite propriétés.

Comme ces étapes sont séquentielles, il est important de définir des animations dans des propriétés qui se trouvent plus loin dans le pipeline. Plus tôt la mise à jour se produit au cours du processus, plus les coûts sont élevés et moins il y a de chances fluide. (Voir Affichage performances pour en savoir plus.)

Bien qu'il puisse être pratique d'animer les propriétés de mise en page, même si ces coûts n'apparaissent pas immédiatement. Les animations doivent être définis en termes de modifications des propriétés composites, dans la mesure du possible.

Définir des animations CSS déclaratives ou utiliser des Animations tout en veillant à animer les éléments composites propriétés, est une excellente première étape pour garantir une animation fluide et efficace. Mais quand même, cela ne garantit pas la fluidité, car même des animations Web efficaces des limites de performances. C'est pourquoi il est toujours important de mesurer vos performances.

Que sont les frames d'animation ?

Les modifications apportées à la représentation visuelle d'une page mettent un certain temps à s'afficher. Un élément visuel génère une nouvelle image d'animation, qui est finalement affichée sur la l'écran de l'utilisateur.

Les écrans se mettent à jour à un certain intervalle, de sorte que les mises à jour visuelles sont regroupées. Nombreux écrans sont mises à jour à intervalles fixes, par exemple 60 fois par seconde (soit 60 Hz). Certains écrans plus modernes peuvent offrir des fréquences d'actualisation plus élevées (les fréquences de 90 à 120 Hz deviennent de plus en plus courantes). Souvent, ces écrans peuvent s'adapter activement entre les fréquences d'actualisation selon les besoins, ou même proposer des fréquences d'images totalement variables.

L'objectif de toute application, comme un jeu ou un navigateur, est de traiter tous ces des mises à jour visuelles groupées et de produire un frame d'animation visuellement complet dans la date limite, à chaque fois. Notez que cet objectif est entièrement différent des autres les tâches importantes du navigateur, telles que le chargement rapide de contenu depuis le réseau, une exécution efficace des tâches JavaScript.

À un moment donné, il peut devenir trop difficile d'effectuer toutes les mises à jour visuelles dans le délai alloué attribué par l'écran. Dans ce cas, le navigateur abandonne une image. Votre écran ne devient pas noir, il se répète. Vous voyez la même mise à jour visuelle pendant un peu plus longtemps, la même image d'animation présenté à l'occasion de frame précédent.

En fait, cela arrive souvent ! Elle n'est pas nécessairement perceptible, surtout pour le contenu statique ou de type document, ce qui est courant sur la plate-forme Web en particulier. Les images supprimées n'apparaissent que s'il y a des éléments visuels importants les mises à jour, telles que les animations, pour lesquelles un flux d'animation constant est nécessaire ; pour afficher un mouvement fluide.

Quels éléments ont un impact sur les images d'animation ?

Les développeurs Web peuvent avoir un impact considérable sur la capacité d'un navigateur à traiter rapidement et afficher et présenter efficacement des mises à jour visuelles !

Voici quelques exemples :

  • Utiliser du contenu trop volumineux ou gourmand en ressources pour pouvoir être décodé rapidement sur le appareil cible.
  • Utilisation d'un trop grand nombre des couches nécessite trop de mémoire GPU.
  • Définir des animations Web ou des styles CSS trop complexes
  • Utiliser des anti-modèles de conception qui désactivent les optimisations rapides de rendu
  • Trop de travail JS sur le thread principal, ce qui entraîne de longues tâches qui bloquent les éléments visuels mises à jour.

Mais comment savoir quand une image d'animation a dépassé son délai et a causé une perte de trame ?

Une méthode possible consiste à utiliser requestAnimationFrame() des sondages, mais elle présente plusieurs inconvénients. requestAnimationFrame() ou "rAF", indique au navigateur que vous souhaitez exécuter une animation et demande une l'occasion de le faire avant l'étape suivante de peinture du pipeline de rendu. Si votre fonction de rappel n'est pas appelée au moment prévu, ce qui signifie qu'un paint n'a pas été exécuté et un ou plusieurs frames ont été ignorés. En interrogeant et en compter la fréquence d'appel de la fonction rAF, vous pouvez calculer une sorte de « frames par seconde » (FPS).

let frameTimes = [];
function pollFramesPerSecond(now) {
  frameTimes = [...frameTimes.filter(t => t > now - 1000), now];
  requestAnimationFrame(pollFramesPerSecond);
  console.log('Frames per second:', frameTimes.length);
}
requestAnimationFrame(pollFramesPerSecond);

L'utilisation du sondage requestAnimationFrame() n'est pas une bonne idée pour plusieurs raisons:

  • Chaque script doit configurer sa propre boucle d'interrogation.
  • Elle peut bloquer le chemin critique.
  • Même si l'interrogation de la fonction rAF est rapide, elle peut empêcher requestIdleCallback() d'être en mesure de programmer de longs blocages inactifs en cas d'utilisation continue dépassent une seule image).
  • De même, l'absence de longs blocs inactifs empêche le navigateur de planifier d'autres les tâches de longue durée (par exemple, une récupération de mémoire plus longue et d'autres tâches en arrière-plan ou le travail spéculatif).
  • Si l'interrogation est activée et désactivée, vous manquerez les cas où le budget des frames a été dépassé.
  • L'interrogation signale des faux positifs si le navigateur utilise fréquence de mise à jour variable (par exemple, en raison de l'état d'alimentation ou de visibilité).
  • Et surtout, il ne capture pas tous les types d'animations mises à jour !

Une tâche trop importante sur le thread principal peut affecter l'affichage des images d'animation. Regardez la vidéo Jank exemple pour voir comment Animation pilotée par rAF, lorsqu'il y a trop de travail sur le thread principal (comme graphique), entraîne une perte de frames, moins de rappels rAF et une diminution du FPS.

Lorsque le thread principal est bloqué, les mises à jour visuelles commencent à s'interrompre. C'est un à-coup !

De nombreux outils de mesure se sont largement concentrés sur la capacité des principaux pour générer des résultats en temps opportun et pour que les images d'animation s'exécutent correctement. Mais ce n'est pas tout ! Prenons l'exemple suivant :

La vidéo ci-dessus montre une page qui injecte régulièrement de longues tâches dans le tableau de bord principal thread. Ces longues tâches gâchent complètement la capacité de la page à fournir certains types de mises à jour visuelles. En haut à gauche, baisse correspondante de requestAnimationFrame() FPS à 0.

Pourtant, malgré ces longues tâches, la page continue de défiler sans problème. Ce En effet, dans les navigateurs récents, le défilement est souvent fil de discussion, entièrement dirigée par le compositeur.

Il s'agit d'un exemple qui contient simultanément de nombreux frames supprimés sur la vue principale mais qu'il y a toujours de nombreux frames de défilement sur le fil de discussion du compositeur. Une fois la longue tâche terminée, le thread principal se met à jour n’a aucune modification visuelle à offrir de toute façon. L'interrogation rAF a suggéré une chute de trame sur 0, mais visuellement, l'utilisateur ne remarquera pas la différence.

Pour les images d'animation, l'histoire n'est pas si simple.

Images d'animation: mises à jour importantes

L'exemple ci-dessus montre que l'histoire ne se limite pas requestAnimationFrame()

Quand les mises à jour et les images d'animation sont-elles importantes ? Voici certains critères qui nous intéressent et sur lesquels nous aimerions avoir votre avis:

  • Mises à jour des threads principal et du compositeur
  • Mises à jour de peinture manquantes
  • Détecter des animations
  • Qualité ou quantité

Mises à jour des threads principal et du compositeur

Les mises à jour des frames d'animation ne sont pas booléennes. Ce n’est pas le cas que les cadres ne peuvent être complètement abandonnés ou entièrement présentées. Il existe de nombreuses raisons pour lesquelles une animation cadre peut être partiellement présenté. En d'autres termes, il peut avoir simultanément contenus non actualisés ainsi que de nouvelles mises à jour visuelles, présentées.

L'exemple le plus courant est lorsque le navigateur n'est pas en mesure de produire une nouvelle mise à jour du thread principal dans le délai imparti, mais a un nouveau thread compositeur de mise à jour (comme l'exemple précédent de défilement filtré).

L'une des principales raisons pour lesquelles l'utilisation d'animations déclaratives est recommandé, car cela permet de diriger une animation entièrement par le thread du compositeur, même si le thread principal est occupé. Ces types des animations peuvent continuer à produire des mises à jour visuelles de manière efficace et en parallèle.

D'autre part, il peut arriver qu'une mise à jour du thread principal disponible pour la présentation, mais seulement après avoir manqué plusieurs délais de rendu. Ici, le navigateur dispose d'une nouvelle mise à jour, mais il ne s'agit peut-être pas de la toute dernière mise à jour.

De manière générale, nous considérons les cadres qui contiennent de nouvelles mises à jour visuelles, sans aucune nouvelle mise à jour visuelle, sous la forme d'un cadre partiel. Les images partielles sont assez justes commun. Dans l'idéal, les mises à jour partielles incluraient au moins les éléments les plus importants des mises à jour visuelles, comme les animations, mais cela ne peut se produire que si les animations par le fil de discussion du compositeur.

Mises à jour de peinture manquantes

Autre type de mise à jour partielle : les contenus multimédias tels que les images ne sont pas terminés décodage et rastérisation à temps pour la présentation du cadre.

Ou, même si une page est parfaitement statique, les navigateurs peuvent toujours prendre du retard sur l'affichage des mises à jour visuelles lors d'un défilement rapide. En effet, les rendus de pixels le contenu situé au-delà de la fenêtre d'affichage visible peut être supprimé pour économiser de la mémoire GPU. Il met du temps à afficher les pixels, et un seul cadre peut être nécessaire tout afficher après un grand défilement, comme un mouvement du doigt. C'est en général appelée damier.

Avec chaque opportunité de rendu d'image, il est possible de suivre la proportion les dernières mises à jour visuelles ont été transmises à l'écran. Mesurer la capacité à le faire sur un grand nombre de trames (ou durée) est communément appelé débit d'images.

Si le GPU est vraiment bloqué, le navigateur (ou la plate-forme) peut même commencer à limite la vitesse à laquelle il tente d'effectuer des mises à jour visuelles, ce qui réduit des fréquences d'images effectives. Bien que, techniquement, cela permet de réduire le nombre mises à jour de trame, visuellement, il apparaîtra toujours comme un débit de trame inférieur.

Pourtant, tous les types de faible débit de trame ne sont pas néfastes. Si la page est principalement inactive et qu'il n'y a pas d'animations actives, une fréquence d'images faible une fréquence d'images élevée permet d'économiser la batterie.

Quand le débit des trames est-il important ?

Détecter des animations

Un débit élevé de frames est important, en particulier pendant les périodes avec des des animations. Les différents types d'animations dépendent des mises à jour visuelles thread spécifique (principal, compositeur ou nœud de calcul), ce qui fait que sa mise à jour visuelle est dépend de ce thread qui fournit sa mise à jour dans le délai imparti. Nous disons qu'un un thread donné affecte la fluidité chaque fois qu'une animation active est dépend de la mise à jour du thread.

Certains types d'animations sont plus faciles à définir et à détecter que d'autres. Les animations déclaratives, ou animations basées sur les entrées de l'utilisateur, sont plus claires à définir que les animations JavaScript implémentées en tant que mises à jour périodiques de l'animation d'animation Propriétés de style.

Même avec requestAnimationFrame(), vous ne peut pas toujours supposer que chaque appel rAF produit nécessairement une ou une animation. Par exemple, utiliser la recherche rAF uniquement pour suivre la fréquence d'images (comme indiqué ci-dessus) ne devraient pas avoir d'incidence sur les mesures de fluidité, car il existe aucune mise à jour visuelle.

Qualité ou quantité

Enfin, la détection des animations et des mises à jour des frames d'animation ne constitue qu'une partie l'histoire, car elle ne capture que le nombre de mises à jour de l'animation, et non qualité.

Par exemple, vous pouvez voir une fréquence d'images stable de 60 FPS lorsque vous regardez une vidéo. Techniquement, c'est parfaitement fluide, mais la vidéo elle-même peut avoir un débit faible ou des problèmes de mise en mémoire tampon du réseau. Cela n'est pas enregistré par les métriques sur la fluidité de l'animation, mais elles peuvent encore être gênantes utilisateur.

Ou un jeu qui utilise <canvas> (peut-être même avec des techniques comme hors écran canevas pour une fréquence d'images stable) peut techniquement être parfaitement fluide des images d'animation, mais l'échec du chargement des éléments de jeu de haute qualité dans la d'une scène ou l'exposition d'artefacts de rendu.

Bien sûr, un site peut avoir de très mauvaises animations 😃

GIF de la vieille école en construction

Je veux dire, je suppose qu'ils étaient plutôt cool pour le moment !

États d'une seule image d'animation

Les images peuvent être partiellement présentées ou les pertes de frames peuvent se produire qui n'affectent pas la fluidité, nous avons commencé à considérer chaque image comme le score d'exhaustivité ou de fluidité.

Voici le spectre des manières d'interpréter l'état d'un seul image d'animation, classée par ordre décroissant:

Aucune mise à jour souhaitée Durée d'inactivité, répétition de l'image précédente.
Parfaitement présenté La mise à jour du thread principal a été validée dans le délai imparti, ou aucune la mise à jour du thread principal était souhaitée.
Partiellement présentée Compositeur uniquement la mise à jour retardée du thread principal n'avait aucun visuel le changement.
Partiellement présentée Compositeur uniquement le thread principal a eu une mise à jour visuelle, mais cela mise à jour n'incluait pas d'animation affectant la fluidité.
Partiellement présentée Compositeur uniquement le thread principal a fait l'objet d'une mise à jour visuelle qui affecte mais une image précédemment obsolète est arrivée et a été utilisée à la place.
Partiellement présentée Compositeur uniquement sans la mise à jour principale souhaitée, la mise à jour du compositeur comporte une animation qui affecte la fluidité.
Partiellement présentée Le compositeur uniquement, mais sa mise à jour n'a pas de qui affecte la fluidité.
Cadre supprimé Aucune mise à jour. Aucune mise à jour du compositeur n'a été choisie, en retard.
Cadre supprimé Une mise à jour du compositeur était souhaitée, mais elle a été retardée.
Frame non actualisé Une mise à jour était souhaitée. Elle a été produite par le moteur de rendu, mais Le GPU ne l'a toujours pas présentée avant la date limite de vsync.

Il est possible de transformer ces états en une certaine note. Et peut-être une façon pour interpréter ce score, considérez qu'il s'agit d'une probabilité d'être observable l'utilisateur. Une seule image abandonnée peut ne pas être très observable, mais une séquence de de nombreuses images abandonnées affectant la fluidité d'une ligne, c'est sûr !

Synthèse: une métrique "Pourcentage d'images abandonnées"

Même s'il peut parfois être nécessaire d'approfondir l'état de chaque d'animation, il est également utile d'attribuer un bref aperçu score pour une expérience.

Parce que les frames peuvent être partiellement présentés et même qu'ils sont complètement ignorés les mises à jour de frames peuvent ne pas affecter la fluidité, nous voulons moins nous concentrer Il ne fait que compter les images, et bien plus encore sur l'étendue à laquelle le navigateur n'est pas en mesure Fournir des informations visuellement complètes le cas échéant

Le modèle mental doit passer de:

  1. Images par seconde, pour
  2. Détecter les mises à jour d'animation importantes et manquantes
  3. Pourcentage d'abandon sur une période donnée.

Ce qui compte, c'est: la proportion de temps passé à attendre des événements importants mises à jour. Nous pensons que cela correspond à la fluidité de l'expérience utilisateur. de contenu Web dans la pratique. Jusqu'à présent, nous avons utilisé ce qui suit comme ensemble initial de métriques:

  • Pourcentage moyen d'abandon:pour toutes les images d'animation non inactives tout au long du toute la chronologie
  • Pourcentage de suppression d'images dans le pire des cas:mesuré sur un glissement d'une seconde des fenêtres de temps.
  • 95e centile du pourcentage d'abandons des images:mesuré sur une seconde des fenêtres de temps glissantes.

Ces scores sont disponibles dès aujourd'hui dans certains outils pour les développeurs Chrome. Bien que ces se concentrent uniquement sur le débit global de frames, nous évaluons également d'autres facteurs tels que la latence des frames.

Essayez par vous-même dans les outils pour les développeurs.

HUD des performances

Chromium dispose d'un HUD performant, dissimulé derrière un drapeau (chrome://flags/#show-performance-metrics-hud). Vous y trouverez pour des éléments tels que les métriques Core Web Vitals, ainsi que pour quelques définitions expérimentales pour la fluidité de l'animation en fonction du pourcentage d'images supprimées au fil du temps.

HUD des performances

Statistiques de rendu des images

Activez "Rendu des images" Statistiques" dans les outils de développement via les paramètres de rendu pour voir en direct les nouvelles images d'animation. qui sont codées par couleur pour différencier les mises à jour partielles des images totalement supprimées mises à jour. Les FPS indiquées ne concernent que les images entièrement présentées.

Statistiques de rendu des images

Visionneuse de frames dans les enregistrements de profils de performances des outils de développement

L'outil DevTools Performance panneau, a depuis longtemps un Cadre lecteur vidéo. Cependant, cette version n'était pas synchronisée avec la façon dont le pipeline de rendu moderne fonctionne réellement. De nombreuses améliorations ont été récemment apportées, Chrome Canary, qui, selon nous, facilitera considérablement le débogage des problèmes d'animation.

Aujourd'hui, vous constaterez que les cadres dans la visionneuse de cadres sont mieux adaptés les limites vsync et un code couleur en fonction de l'état. Il n'y a toujours pas plein de visualisation pour toutes les nuances présentées ci-dessus, mais nous prévoyons d'en ajouter d'autres dans un avenir proche.

Visionneuse de frames dans les outils pour les développeurs Chrome

Traçage Chrome

Enfin, avec le traçage Chrome, l'outil de prédilection pour plonger dans les détails, vous pouvez enregistrer un "rendu de contenu Web" trace via la nouvelle interface Perfetto (UI) (ou about:tracing) et à explorer en détail graphique. Cela peut être une tâche intimidante, mais il y a quelques choses récemment ajouté à Chromium pour vous faciliter la tâche. Vous pouvez obtenir un aperçu disponibles dans le cadre du programme Cadre document.

Grâce aux événements de trace, vous pouvez déterminer de manière définitive:

  • Quelles animations sont en cours d'exécution (à l'aide d'événements nommés TrackerValidation) ?
  • Obtenir la timeline exacte des images d'animation (en utilisant des événements nommés PipelineReporter).
  • Si les mises à jour d'animation sont saccadées, déterminez exactement ce qui bloque votre d'une animation de s'exécuter plus rapidement (en utilisant la répartition des événements dans PipelineReporter événements).
  • Combien de temps faut-il pour obtenir une mise à jour visuelle pour les animations basées sur les entrées ? (à l'aide d'événements nommés EventLatency).

Rapporteur de pipeline de traçage Chrome

Étape suivante

L'initiative Web Vitals vise à fournir des métriques et des conseils la création d'expériences utilisateur de qualité sur le Web. Métriques basées sur des ateliers, telles que Total les temps de blocage sont essentiels pour détecter et diagnostiquer les éventuels problèmes d'interactivité. Nous prévoyons de Concevoir une métrique similaire basée sur des ateliers afin d'assurer la fluidité des animations

Nous vous tiendrons au courant dès que nous continuerons à travailler sur des idées pour concevoir un une métrique complète basée sur les données de chaque frame d'animation.

À l'avenir, nous aimerions également concevoir des API qui permettront de mesurer la fluidité de l'animation pour les utilisateurs réels field ainsi que dans l'atelier. Nous vous communiquerons prochainement plus d'informations à ce sujet.

Commentaires

Nous sommes fiers des dernières améliorations et outils pour les développeurs disponible dans Chrome pour mesurer la fluidité des animations. Essayez ces outils, effectuez une analyse comparative de vos animations et dites-nous où cela mène !

Vous pouvez envoyer vos commentaires au web-vitals-feedback Google groupe avec "[Métriques de fluidité]" dans la ligne d'objet. Nous cherchons vraiment Nous avons hâte de connaître votre avis.