Temps de rendu CSS et poids d'affichage de la page

Introduction

Si vous êtes du genre à s'informer sur le fonctionnement des navigateurs, par exemple, vous savez déjà qu'il y a eu récemment des articles intéressants détaillant le moteur de rendu ou le mode composite accéléré par le GPU de Chrome. Tout d'abord, Accélération du rendu dans Chrome: le modèle de calque est une excellente introduction à la façon dont Chrome utilise le concept des calques pour dessiner les pages. Si vous souhaitez en savoir plus sur la composition accélérée par GPU dans Chrome, vous découvrirez comment Chrome utilise ces couches ainsi que le GPU pour afficher votre page.

La question philosophique

Ayant passé beaucoup de temps à écrire des rastériseurs logiciels pour des applications 3D, il est apparu que certaines propriétés CSS devaient présenter des performances variables lors du tracé d'une page. Par exemple, la rastérisation d'une petite image à l'écran est une opération algorithmique complètement différente, qui dessine une ombre projetée sur une forme arbitraire. La question est donc devenue la suivante: comment différentes propriétés CSS affectent-elles l'épaisseur d'affichage de votre page ?

Mon objectif était de classer un grand nombre de propriétés/valeurs CSS en fonction de leur temps de rendu, afin de mieux identifier les types de propriétés CSS les plus performants. Pour ce faire, j'ai écrit une automatisation avec du ruban adhésif et de la chewing-gum pour essayer d'ajouter une visibilité numérique aux temps de peinture CSS. Cette opération a fonctionné comme suit:

  • Générez une suite de pages HTML individuelles, chacune avec un seul élément DOM et des permutations de propriétés CSS associées.
  • Exécutez un script d'automatisation qui, pour chaque page, va :
    • Lancer Chrome
    • Charger une page
    • Créer une image de Skia pour la page
    • Exécutez chaque image Skia prise via Skia Benchmark pour connaître la durée.
  • Vérifiez le temps nécessaire et émerveillez-vous devant les résultats. (Cette partie est importante...)

Avec cette configuration, nous générons une suite de pages HTML, où chaque page contient une permutation unique de propriétés et de valeurs CSS. Par exemple, voici deux fichiers HTML:

<style>
#example1 {
    background: url(foo.png) top left / 50% 60%;
    padding: 20px; 
    margin-top: 10px;
    margin-right: 20px; 
    text-align: center;
}
</style>
<div id="example1">WOAH</div>

Deuxièmement, il est plus complexe

<style>
#example1 {
    background-color:#eee;
    box-shadow: 1px 2px 3px 4px black;
    border-radius: 50%;
    background: radial-gradient(circle closest-corner, white, black);
    padding: 20px; 
    margin-top: 10px;
    margin-right: 20px; 
    text-align: center;
}
</style>
<div id="example1">WOAH</div>

Comme variante du dernier exemple, ci-dessous, où nous ne modifions que la valeur du dégradé radial:

<style>
#example1 
{
    background-color:#eee;
    box-shadow: 1px 2px 3px 4px black;
    border-radius: 50%;
    background: radial-gradient(farthest-side, white, black);
    padding: 20px; 
    margin-top: 10px;
    margin-right: 20px; 
    text-align: center;
}
</style>
<div id="example1" style="padding: 20px; margin-top: 10px;margin-right: 20px; text-align: center;">WOAH</div>

Chaque page est ensuite chargée dans une nouvelle instance de Chrome (afin de s'assurer que les codes temporels ne sont pas faussés par des états obsolètes lors des recharges de pages), et une image de Skia (*.SKP) est utilisée pour évaluer les commandes Skia utilisées pour peindre la page. Une fois que les fichiers SKP ont été générés pour chaque fichier HTML, nous exécutons un autre lot pour transférer les fichiers *.SKP via l'application Skia Benchmark (créée à partir du code source de Skia), qui élimine le temps moyen nécessaire pour afficher cette page.

Évaluer les données

À partir de là, nous pouvons désormais représenter grossièrement la quantité de données qu'il faut à une suite de propriétés CSS pour peindre. Nous pouvons aussi commencer à classer les propriétés CSS en fonction de leurs performances de peinture. Voici un grand graphique créé avec la version bêta de Chrome 27, qui représente l'ensemble des données temporelles de ce processus. Notez que toutes les données sont susceptibles de changer à mesure que Chrome s'accélère au fil du temps.

Délais pour toutes les permutations du test

Chaque barre verticale représente le temps de rendu d'une page avec une seule combinaison de propriétés CSS (agrandie par 100 ; la valeur d'échelle réelle de ce graphique est de 0,1,56 ms). Il y a beaucoup de belles lignes, mais sous cette forme, elles sont un peu inutiles ; nous devons faire de l'exploration de données pour trouver des tendances utiles.

Tout d'abord, nous en trouvons la preuve que certaines propriétés CSS sont tout simplement plus chères à afficher que d'autres. Par exemple, le dessin d'une ombre projetée sur un élément DOM implique une opération en plusieurs passages avec des splines et d'autres éléments désagréables, par opposition à l'opacité, qui devrait être plus facile à afficher.

Temps nécessaire pour afficher un élément comportant une seule propriété CSS

Deuxièmement, et plus intéressant encore, les combinaisons de propriétés CSS peuvent avoir un temps de rendu supérieur à la somme de leurs parties. Du point de vue d'un observateur, c'est un peu étrange, nous pourrions nous attendre à ce que A+B = C, et non 2,2C. Par exemple, en ajoutant box-shadow et border-radius-stroke :

Délais pour toutes les permutations du test

Ce qui est très intéressant à ce sujet, c'est qu'il ne s'agit pas seulement de la propriété box-shadow elle-même, mais plutôt de cette permutation de valeur spécifique. L'exemple ci-dessous présente un regroupement de box-shadow : 50% et border-radius avec des variantes de valeurs.

Délais pour toutes les permutations du test

En regardant les données, cela se poursuit pendant un certain temps. Il existe un grand nombre de combinaisons bizarres, et ma suite de tests ne les touche pas toutes. Il existe encore des tonnes de tests et de combinaisons qui pourraient donner des résultats intéressants.

Déterminer la pondération de rendu de votre page

Grâce à la possibilité de suivre les délais d'affichage de chaque élément de votre page, les développeurs peuvent commencer à évaluer le poids de rendu de la page et son impact sur la réactivité de votre site. Voici quelques conseils pour commencer

  1. Utilisez le mode Peinture continue de Chrome dans les outils pour les développeurs Chrome afin de comprendre ce que les propriétés CSS vous coûtent.
  2. Intégrez des examens CSS à votre processus de révision de code existant pour détecter les problèmes de performances. Recherchez dans votre CSS des endroits connus pour être plus chers, comme les dégradés et les ombres. Demandez-vous si vous en avez vraiment besoin ici.
  3. En cas de doute, privilégiez toujours de meilleures performances. Vos utilisateurs ne se souviendront peut-être pas de la largeur de la marge intérieure de vos colonnes, mais ils se souviendront de ce qu'ils ressentent lorsqu'ils visitent votre site.

Pour conclure

L'un des points les plus intéressants de cette expérience, c'est que les délais ne sont pas les mêmes à chaque version de Chrome (nous espérons qu'elle deviendra plus rapide ;). La surface du logiciel du navigateur change constamment. Qu'est-ce qui est lent aujourd'hui, pourrait l'être demain ? Vous pouvez retenir cet article pour éviter de placer box-shadow: 1px 2px 3px 4px un élément qui possède déjà border-radius:5. Cependant, il est plus important de retenir que les propriétés CSS affectent directement le temps de rendu des pages.

Références