J'ai récemment publié Learn WCs et si vous l'avez vu, vous avez probablement remarqué l'animation en arrière-plan, où les cercles colorés se déplacent en diagonale sur l'écran. Cela ressemble à ceci :
Cela fonctionne bien sur Chrome et Safari, mais j'ai remarqué une forte baisse des performances sur Firefox.
Les performances étaient si mauvaises que j'ai directement désactivé cette animation dans Firefox.
L'animation est construite à l'aide de deux div imbriqués. Le div externe est le premier enfant de la balise body du site.
L'élément .background-gradient est chargé de créer un dégradé qui s'étend sur toute la largeur et la hauteur de son conteneur parent. Comme ceci :
Le masque .background-mask externe est responsable de deux choses :
Cela garantit que la couleur des points est la couleur du dégradé directement en dessous :
Voici le CSS pour tout ce que j'ai décrit ci-dessus :
.background-mask { --mask-size: 24px; /* Position Styles */ position: fixed; width: 100%; height: 100%; z-index: -1; /* Mask Styles */ mask-image: radial-gradient(black 2px, transparent 2px); mask-size: var(--mask-size) var(--mask-size); mask-position: 0px 0px; animation: mask-move 3s infinite linear; } .background-gradient { background: var(--red); background-image: var(--gradient); width: 100%; height: 100%; } @keyframes mask-move { 0% { mask-position: 0px 0px; } 100% { mask-position: var(--mask-size) var(--mask-size); } } @media (prefers-reduced-motion: reduce) { .hero-background-mask { animation: none; } }
Si vous souhaitez en savoir plus sur les masques en CSS, je peux vous recommander cet article complet d'Ahmad Shadeed
Toutes les propriétés CSS ne s'animent pas de la même manière. Sans trop entrer dans la façon dont le navigateur affiche le code HTML sur la page (même si je l'ai décrit ici), il passe par une poignée d'étapes. Les trois étapes qui nous intéressent sont :
L'ordre du pipeline ressemble à ceci :
Mise en page → Peinture → Composite
Les processus de mise en page et de peinture peuvent être gourmands en CPU, il est donc important d'essayer de réduire le nombre de fois où votre CSS déclenche les étapes du pipeline*.* Le navigateur aide dans une certaine mesure en optimisant les performances de certaines propriétés, d'autres ignorez des étapes entières du pipeline de rendu et d'autres peuvent tirer parti de l'accélération matérielle pour déplacer le calcul du CPU vers le GPU.
L'animation de certaines propriétés, comme translation et opacity , évite de déclencher une mise en page et utilise l'accélération matérielle.
Malheureusement, ce n'est pas le cas lors de l'animation de la position du masque. J'ai jeté un œil à Chrome et j'ai vu que le nombre de peintures pour le div d'arrière-plan augmentait à chaque image. Au bout de quelques secondes, il avait déjà déclenché une peinture plus de 1 000 fois.
Même avec ce nombre de peintures élevé, l'animation sur Chrome est fluide. Cependant, cela semble super bizarre sur Firefox. Malheureusement, je n’ai pas trouvé de moyen de mesurer le nombre de peintures sur Firefox, donc toutes les hypothèses que je fais sur les mauvaises performances de Firefox ne sont que des conjectures.
Ce que j'ai remarqué, c'est que l'animation convient aux petits appareils, mais s'aggrave à mesure que la taille de l'écran augmente. Ma théorie de travail est que Firefox ne regroupe pas les déclencheurs de mise en page pour chacun des masques 24x24, ce qui provoque un ralentissement du FPS lorsque davantage de masques 24x24 sont présents. Encore une fois, je me trompe peut-être complètement.
Au lieu d'animer des propriétés CSS mal optimisées comme mask-position , je devais m'appuyer sur les propriétés les plus performantes, comme Translate.
La solution n'était pas de déplacer les masques de 24 pixels, mais de déplacer tout l'élément d'arrière-plan à l'aide de la propriété Translate.
D'un point de vue abstrait, voici à quoi ressemble l'animation :
Voici le changement de deux lignes dans le CSS :
/* --mask-size = 24px */ @keyframes mask-move { 0% { transform: translate(calc(var(--mask-size) * -1), calc(var(--mask-size) * -1)); } 100% { transform: translate(0px, 0px); } }
Le navigateur n'anime plus la position du masque, ce qui déclenchait une mise en page sur chaque image. Même si l’arrière-plan bouge sur chaque image, la translation ne déclenche pas de mise en page ni de peinture. Vous pouvez voir que le seul peint deux fois, contre 1 000 par minute.
Les téléspectateurs aux yeux d’aigle auront repéré un problème. Si vous vous en souvenez, la hauteur et la largeur de l'arrière-plan remplissent la fenêtre. Déplacer l'arrière-plan vers la gauche et vers le haut de 24 pixels nous laisse cet espace vide dans la fenêtre.
Le résoudre est aussi simple que d'ajouter la taille du masque à la largeur et à la hauteur du conteneur :
.background-mask { --mask-size: 24px; width: calc(100% var(--mask-size)); height: calc(100% var(--mask-size)); }
Regardons à nouveau Firefox :
Ce n'est peut-être pas une solution parfaite, mais c'est toujours un peu satisfaisant de réaliser une astuce CSS amusante fumée et miroirs.
Clause de non-responsabilité: Toutes les ressources fournies proviennent en partie d'Internet. En cas de violation de vos droits d'auteur ou d'autres droits et intérêts, veuillez expliquer les raisons détaillées et fournir une preuve du droit d'auteur ou des droits et intérêts, puis l'envoyer à l'adresse e-mail : [email protected]. Nous nous en occuperons pour vous dans les plus brefs délais.
Copyright© 2022 湘ICP备2022001581号-3