Il est essentiel d'éviter les peintures pour obtenir une fréquence d'images fluide, en particulier sur mobile. Cependant, il arrive parfois que la peinture apparaisse dans les endroits les plus inhabituels. Cet article explique pourquoi les GIF animés peuvent entraîner des peintures inutiles et la correction incroyablement simple que vous pouvez appliquer.
L'élégance sous toutes ses coutures
Comme vous le savez probablement, les navigateurs récents peuvent peindre des groupes d'éléments DOM en "images", appelées "calques". La page est parfois composée d'un seul calque, parfois des centaines, voire dans de rares cas, des milliers !
Lorsque les éléments DOM sont regroupés dans un calque et que l'un d'entre eux change visuellement, nous devrons peindre non seulement l'élément modifié, mais aussi tous les autres éléments du calque qui chevauchent l'élément modifié. Si vous superposez un élément à un élément, les pixels écrasés sont "perdus" définitivement. Si vous souhaitez récupérer les pixels d'origine, vous devez les repeindre.
C'est pourquoi nous souhaitons parfois isoler un élément des autres afin d'éviter d'avoir à repeindre les autres éléments qui n'ont pas modifiés. Par exemple, lorsque vous combinez un en-tête de page fixe avec du contenu à faire défiler, vous devez repeindre l'en-tête chaque fois que le contenu défile, ainsi que le contenu nouvellement visible. En plaçant l'en-tête dans une couche distincte, le navigateur peut optimiser le défilement. Lorsque vous faites défiler l'écran, le navigateur peut déplacer les calques (probablement à l'aide du GPU) et éviter de repeindre l'un ou l'autre de ces calques.
Chaque couche supplémentaire augmente la consommation de mémoire et affecte les performances. L'objectif est donc de regrouper la page en le moins de couches possible tout en maintenant de bonnes performances.
Qu’est-ce que tout cela a à voir avec les GIF animés ?
Jetons un coup d'œil à cette image:
Il s'agit d'une configuration de couche potentielle pour une application simple. Il y a quatre couches: trois d'entre elles (couche 2 à 4) sont des éléments d'interface ; la couche arrière est un chargeur, qui se trouve être un GIF animé. Dans le flux normal, vous affichez le chargeur (couche 1) pendant le chargement de votre application, puis, une fois que tout est terminé, les autres couches s'affichent. Mais voici le principe: vous devez masquer le GIF animé.
Mais pourquoi dois-je le cacher ?
Bonne question ! Dans un monde parfait, le navigateur vérifierait simplement la visibilité du GIF pour vous et éviterait de peindre automatiquement. Malheureusement, vérifier si le GIF animé est masqué ou visible à l'écran coûte généralement plus que de simplement le peindre.
Dans le meilleur des cas, le GIF se trouve dans sa propre couche et le navigateur n'a qu'à le peindre et à le télécharger sur le GPU. Toutefois, dans le pire des cas, tous vos éléments pourraient être regroupés en une seule couche, et le navigateur devra alors repeindre chaque élément. Une fois l'opération terminée, il doit tout de même tout importer sur le GPU. Tout cela fonctionne pour chaque image GIF, même si l'utilisateur ne peut même pas voir le GIF !
Sur les ordinateurs de bureau, vous pouvez probablement vous en sortir avec ce type de comportement de peinture, car les processeurs et les GPU sont plus puissants, et la bande passante est importante pour transférer les données entre les deux. Sur mobile, cependant, la peinture est extrêmement chère, vous devez donc être particulièrement vigilant.
Quels sont les navigateurs concernés ?
Comme c'est souvent le cas, les comportements peuvent varier d'un navigateur à l'autre. Aujourd'hui, Chrome, Safari et Opera sont tous repeints, même si le GIF est masqué. Firefox, en revanche, détecte que le GIF est masqué et qu'il n'est pas nécessaire de le repeindre. Internet Explorer reste quelque peu ressemblant à une boîte noire, et même dans IE11 (puisque les outils F12 sont toujours en cours de développement), rien n'indique si un repeinture a lieu ou non.
Comment savoir si je rencontre ce problème ?
Le moyen le plus simple consiste à utiliser l'option "Afficher les rectangles de peinture" dans les outils pour les développeurs Chrome. Chargez les outils de développement, appuyez sur la roue dentée en bas à droite () et sélectionnez Afficher les rectangles de peinture dans la section Rendu.
Maintenant, tout ce que vous avez à faire est de rechercher un rectangle rouge comme celui-ci:
Le petit cadre rouge à l'écran indique que Chrome repeint quelque chose. Vous savez qu'un GIF de chargement est caché derrière les autres éléments. Par conséquent, lorsque vous voyez une case rouge comme celle-ci, vous devez masquer les éléments visibles et vérifier si vous avez laissé le GIF animé tourner. Si nécessaire, vous devez insérer du code CSS ou JavaScript pour appliquer display: none
ou visibility: hidden
à lui-même ou à son élément parent. S'il ne s'agit que d'une image de fond, vous devez bien sûr la supprimer.
Pour voir un exemple de ce comportement sur un site en ligne, consultez Allegro, où l'image de chaque produit comporte un GIF de chargement qui est masqué plutôt que explicitement masqué.
Conclusion
Pour atteindre 60 FPS, vous devez effectuer uniquement le rendu de la page, et rien d'autre. L'élimination des peintures superflues est une étape essentielle pour atteindre cet objectif. Les GIF animés qui restent en cours d'exécution peuvent déclencher des peintures inutiles. Vous pouvez les trouver et les déboguer facilement à l'aide de l'outil "Afficher les rectangles de peinture" des outils de développement.
Vous n'avez pas laissé le GIF animé du chargeur de chaton s'exécuter indéfiniment, n'est-ce pas ?