--- title: Chronologie slug: Tools/Performance/Waterfall translation_of: Tools/Performance/Waterfall original_slug: Outils/Performance/Waterfall ---
La chronologie vous donne des indications sur les opérations qu'effectue le navigateur lorsqu'il fait tourner une page web ou une application. Cet outil se base sur l'idée que les opérations qu'effectue un navigateur peuvent être divisées en plusieurs types : exécution du JavaScript, mise à jour du layout, et ainsi de suite... Ainsi que l'idée qu'à n'importe quel point donné dans le temps, le navigateur effectue l'une ou l'autre de ces actions.
Donc, si vous voyez un problème de performance - une chute du frame rate par exemple - vous pouvez utiliser la chronologie pour voir ce que le navigateur faisait à ce moment de l'enregistrement.
L'axe X représente le temps. Les opérations enregistrées, appelées marqueurs sont affichées sous la forme de barres de couleur horizontales. Ces marqueurs sont disposés en cascade pour refléter le caractère séquentiel de l'exécution du navigateur.
Lorsqu'un marqueur est sélectionné, des informations supplémentaires sur celui-ci s'affichent dans le panneau de droite. Ces informations intègrent la durée du marqueur et quelques informations spécifiques de son type.
Les marqueurs possèdent un code couleur et un libellé. Les opérations suivantes sont enregistrées :
Nom et description | Couleur | Informations détaillées |
---|---|---|
Le code JavaScript qui est exécuté en réponse à un évènement DOM. |
|
|
Les fonctions JavaScript exécutées dans la page ont le libellé de la raison pour laquelle la fonction a été appelée : Script Tag |
|
|
Parse HTML Le temps passé à parser le HTML de la page. |
|
|
Parse XML Le temps passé à parser le XML de la page. |
|
|
Recalcul des styles Le calcul des styles qui s'appliquent aux éléments de la page. |
|
|
Layout Le calcul des positions et de la taille des éléments de la page. Cette opération est parfois appelée "reflow". |
||
Paint Affichage des pixels à l'écran |
||
Ramasse-miettes évènement de garbage collection. Les évènements GC non incrémentaux sont nommés "non incrémentiel". |
|
|
Cycle Collection Récupération des structures de données C++ qui sont en "reference-count" Semblable au ramasse-miette, mais pour les objets C++. Voir l'article de blog de Kyle Huey sur le cycle collection. |
|
|
Réduction d'arbre de ramasse-miettes Préparation/préoptimisation pour le Cycle Collection. |
Type
|
|
Console La période entre les appels à |
|
|
Timestamp Un appel unique à |
|
|
DOMContentLoaded L'évènement |
||
Load L'évènement |
||
Évènement dans le thread principal du worker Affiché lorsque le thread principal envoie un message à un worker, ou reçoit un message d'un worker. |
Un parmi :
|
|
Worker event in worker thread Affiché lorsque le worker envoie un message à un worker, ou reçoit un message du thread principal. |
Un parmi :
|
Les marqueurs et leurs couleurs sont les mêmes dans la chronologie que dans la vue d'ensemble de la chronologie.
Il est possible de contrôler quels marqueurs sont affichés en utilisant le bouton dans la barre d'outils :
Le contenu de l´enregistrement dépend énormément des opérations réalisées par le site : Les sites utilisant beaucoup de JavaScript auront un profil à dominance orange, alors que les sites à contenu visuel dynamique auront beaucoup de violet et de vert. Cependant certains motifs communs peuvent vous indiquer de possibles problèmes de performance.
Le motif suivant est très courant dans la vue de la chronologie :
C'est une visualisation de l´algorithme de base qu'utilise le navigateur pour mettre à jour la page en réponse à un évènement :
Cette séquence doit se terminer en une seule image, puisque l'écran n'est pas mis à jour avant qu'elle soit terminée. Il est communément admis que 60 images/secondes est la vitesse à laquelle les animations apparaîtront fluides. Pour un taux de 60 images/secondes, cela laisse au navigateur 16,7 millisecondes pour exécuter le flow complet.
Il est important pour la réactivité à ce que le navigateur n´ait pas à passer par toutes ces étapes à chaque fois :
width
, display
, font-size
, ou top
, provoqueront un « reflow ». Par contre, modifier des propriétés qui ne changent par la géométrie ou le positionnement, telles que color
ou opacity
, n'en feront rien.transform
, le navigateur utilisera une couche séparée pour l'élément transformé, et n'aura peut-être même pas à faire un repaint si l'élément est déplacé : Sa nouvelle position est traitée dans la composition.L'article Animer des propriétés CSS montre qu'animer différentes propriétés CSS peut donner des résultats de performance différents, et comment la chronologie peut aider à le voir.
Par défaut, le JavaScript des pages web est exécuté sur le même thread que celui que le navigateur utilise pour les mises à jour de layout, les repaints, les évènements DOM et ainsi de suite. Cela signifie que des fonctions JavaScript qui mettent longtemps à s´exécuter peuvent causer des ralentissements (jank). Les animations ne seront pas fluides et le site pourra même freezer.
En utilisant l'outil frame rate et la « chronologie », il est facile de voir lorsque des fonctions JavaScript posent problème. Dans la capture d´écran ci-dessous, un zoom a été fait sur une fonction JS qui cause une chute du frame rate :
L'article JavaScript Intensif montre comment la « chronologie » peut mettre en évidence les problèmes de réactivité causés par des fonctions JavaScript trop gourmandes, et comment utiliser des méthodes asynchrones pour garder le thread principal réactif.
Certains effets tels que box-shadow
, peuvent être coûteux ; surtout lors de transitions où le navigateur doit recalculer cet effet à chaque image. Si vous remarquez des chutes de frame rate surtout lors d'opérations et transitions graphiques couteuses, recherchez les longs marqueurs verts (repaint) dans la chronologie.
Les marqueurs rouges dans la chronologie représentent le passage du ramasse-miettes (GC), pour lequel SpiderMonkey (le moteur JavaScript de Firefox) parcourt la pile à la recherche d´éléments en mémoire qui ne sont plus accessible pour les libérer. La GC est un indice de performance, car lorsqu’elle « tourne », le moteur JavaScript doit être en pause et donc le programme est mis en pause et ne répondra pas.
Pour aider à réduire la durée de ces pauses, SpiderMonkey implémente une GC morcelée. Cela signifie qu´il peut faire de la garbage collection par petites « passes », permettant au programme de tourner entre celles-ci. Parfois, le moteur à besoin de réaliser une garbage collection complète et non par morceaux et alors, le programme a besoin d'attendre la fin de cette opération.
Pour essayer d’éviter les évènements GC et surtout les passages complets, il est sage de ne pas essayer d'optimiser pour l'implémentation spécifique du moteur JavaScript. SpiderMonkey utilise un ensemble complexe d'heuristiques pour déterminer quand la GC est nécessaire, et quand une GC non incrémentale en particulier est nécessaire. En général cependant :
Lorsque la Chronologie enregistre un marqueur GC, cela indique :
Deux marqueurs peuvent être contrôlés par des appels à la console API : "Console" et "Timestamp".
Ces marqueurs permettent de marquer une section spécifique de l'enregistrement.
Pour faire un marqueur console, il faut appeler console.time()
au début d'une section, et console.timeEnd()
à la fin. Ces fonctions prennent un argument qui est le nom de la section.
Par exemple si nous avons un code comme ceci :
var iterations = 70; var multiplier = 1000000000; function calculatePrimes() { console.time("calculating..."); var primes = []; for (var i = 0; i < iterations; i++) { var candidate = i * (multiplier * Math.random()); var isPrime = true; for (var c = 2; c <= Math.sqrt(candidate); ++c) { if (candidate % c === 0) { // not prime isPrime = false; break; } } if (isPrime) { primes.push(candidate); } } console.timeEnd("calculating..."); return primes; }
La sortie de la Chronologie ressemblera à ceci :
Le marqueur est nommé par l'argument passé à console.time()
, et lorsque le marqueur est sélectionné, il est possible de voir la pile du programme dans l'encadré sur le coté droit.
Nouveau dans Firefox 41.
À partir de Firefox 41, l'encadré de droite affichera également la stack à la fin de la période. C´est à dire au moment où console.timeEnd()
a été appelé. Si console.timeEnd()
a été appelé par la résolution d'une Promise
, l'encadré affichera également le label "(Async: Promise)", sous lequel sera affiché la "async stack" : Il s'agit de la pile d'appels au moment où la promise a été faite.
Par exemple, avec ce code :
var timerButton = document.getElementById("timer"); timerButton.addEventListener("click", handleClick, false); function handleClick() { console.time("timer"); runTimer(1000).then(timerFinished); } function timerFinished() { console.timeEnd("timer"); console.log("ready!"); } function runTimer(t) { return new Promise(function(resolve) { setTimeout(resolve, t); }); }
La Chronologie affichera un marqueur pour la période entre time()
et timeEnd()
, et s’il est sélectionné, la pile async apparaitra dans l'encadré :
Les Timestamps permettent de marquer un instant dans l'enregistrement.
Pour faire un timestamp, il faut appeler console.timeStamp()
. Il est possible de passer un argument pour nommer le timestamp.
Par exemple, supposons que nous adaptions le code au-dessus pour faire un timestamp toutes les 10 itérations de la boucle ayant pour nom le nombre de l'itération :
var iterations = 70; var multiplier = 1000000000; function calculatePrimes() { console.time("calculating..."); var primes = []; for (var i = 0; i < iterations; i++) { if (i % 10 == 0) { console.timeStamp(i.toString()); } var candidate = i * (multiplier * Math.random()); var isPrime = true; for (var c = 2; c <= Math.sqrt(candidate); ++c) { if (candidate % c === 0) { // not prime isPrime = false; break; } } if (isPrime) { primes.push(candidate); } } console.timeEnd("calculating..."); return primes; }
Dans la Chronologie, vous verrez quelque chose comme ceci :