Informations sèches | 7 façons d'optimiser les performances d'animation des billets de train Ctrip

A propos de l'auteur

Kay Huang est concepteur visuel senior chez Ctrip, se concentrant sur les styles et les animations front-end.

1. Origines

La page marketing des billets de train de Ctrip utilise CSS pour créer des animations depuis de nombreuses années, ce qui améliore considérablement la riche expérience visuelle que les animations offrent à la page. Cependant, au cours du processus de développement, nous avons également rencontré des problèmes liés aux performances et des commentaires des utilisateurs, tels qu'une animation de tête bloquée, un temps d'ouverture de page long et un temps de chargement long de certaines données après l'ouverture de la page. Afin de résoudre ces problèmes, nous avons utilisé des outils de détection de performances pour localiser le problème et consulté le code source, les documents et d'autres ressources pour résoudre le problème, créant ainsi cet article.

2. Optimisation du rendu

Pour optimiser les performances de l'animation, vous devez d'abord comprendre comment le navigateur restitue les éléments. Le processus de rendu du navigateur comprend les quatre étapes suivantes :

a. Calculer le style de l'élément (éventuellement recalculé par script) ;

b. Générer la forme géométrique et la position (mise en page) de chaque élément ;

c. Dessinez chaque pixel du calque (initialisez le dessin et effectuez le dessin) ;

29e0ff208044b6062690fb05944c68c2.jpeg

d. Dessinez le calque à l'écran (fusionnez les calques de rendu).

Pour l'animation CSS3, chaque image doit passer par le processus ci-dessus. Concernant la dernière étape de fusion des calques de rendu (peut être comparée aux calques de Photoshop), le navigateur créera des calques de rendu indépendants à des occasions précises. Chaque calque de rendu est dessiné indépendamment par le GPU sans s'affecter les uns les autres. Enfin, le navigateur fusionne les calques de rendu couches. . C'est une opération moins coûteuse.

Théoriquement, plus le FPS est élevé, plus l'animation sera fluide. Actuellement, le taux de rafraîchissement de l'écran de la plupart des appareils est de 60 fois/seconde, donc d'une manière générale, l'effet d'animation est meilleur lorsque le FPS est de 60 images/s, ce qui est le le temps consommé par image (budget d'image) est de 16,67 ms.

3. Solutions

Comme mentionné ci-dessus, le navigateur a quelques travaux de finition à faire, donc tout le travail doit être terminé dans un délai de 10 ms. Si l'animation déclenche la mise en page, cela équivaut à la deuxième étape du redessin. Si elle est redessinée, le temps de rendu du navigateur dépassera certainement 16 ms, alors notre page sera bloquée. S'il s'agit d'un terminal mobile, alors ce sera plus lent, donc si nous voulons optimiser, nous devons passer directement de la première étape à la quatrième étape.

1bf24423c3a337cc49f5e2eb0b308e40.jpeg

Ci-dessous, j'ai écrit sept façons d'optimiser les performances de l'animation. Certaines d'entre elles passent directement de la première étape à la quatrième étape, et il existe également d'autres considérations d'optimisation quotidiennes.

3.1 Activer l'accélération GPU

La propriété Transform peut appliquer des transformations 2D ou 3D aux éléments, permettant aux éléments d'être sélectionnés, mis à l'échelle, déplacés et inclinés.

Dans la vie quotidienne, nous pouvons utiliser left/top et traduire pour réaliser le déplacement des éléments, mais en fait il y a quand même une certaine différence de performance car l'attribut transform ne changera pas la disposition de lui-même et de ses éléments environnants, il aura un impact sur l’ensemble de l’élément.

Créons d'abord une animation en utilisant les propriétés haut/gauche pour voir l'effet.

<style>
      .heart{animation: heartbeat 4s infinite;width:50px;height:50px;background:red;position:absolute;left:30px;top:30px;}
      @keyframes heartbeat{
          0%{top:30px;left:30px;}
          25%{top:30px;left:230px;}
          50%{top:230px;left:230px;}
          75%{top:230px;left:30px;}
      }
</style>

Si vous utilisez les DevTools du navigateur Chrome pour le visualiser, vous pouvez voir que les carrés rouges sont tous des redessins de mise en page.

Il y a tellement de cases rouges et de numéros d'images dans l'image car le navigateur effectuera beaucoup de calculs et l'animation se figera.

Parce que chaque image change, le navigateur met en page, dessine et transfère de nouveaux bitmaps vers la mémoire du GPU. Bien qu'il ne change que la position de l'élément, il est susceptible de changer la position de ses éléments enfants de manière synchrone, le navigateur devra donc recalculer Une fois la mise en page calculée, le thread principal régénérera le bitmap de l'élément.

8b63f9125bae7cc53134c482070e5a7b.png

Maintenant, remplacez l'animation par une transformation :

<style>
      .heart{animation: heartbeat 1s;width:50px;height:50px;background:red;}
      @keyframes heartbeat{
          0%{transform: translate(30px,30px);}
     25%{transform: translate(30px,230px);}
       50%{transform: translate(230px,230px);}
          75%{transform: translate(230px,30px);}
      }
</style>

En analysant à nouveau, nous pouvons voir qu'il n'y a pas de carré de redessinage rouge et qu'il n'y a qu'un seul numéro d'image, nous savons donc que l'animation sera définitivement fluide et soyeuse.

Étant donné que l'attribut transform ne modifie pas la disposition de lui-même et des éléments environnants, il aura un impact global sur l'élément.

40929dec4e129337543546521d15d241.png

Nous pouvons modifier la position, la rotation, la taille, etc. du nœud via la transformation du nœud. Nous utilisons généralement les attributs left et top pour modifier la position du nœud, mais comme mentionné ci-dessus, left et top déclencheront le relais, et le coût de modification est assez élevé. Une meilleure alternative consiste à utiliser la traduction, qui ne déclenche pas de relais.

3.2 Évitez d'utiliser des propriétés CSS qui affectent les performances

Ces propriétés peuvent avoir un impact sur les performances car elles nécessitent des calculs et un rendu complexes, notamment lorsqu'elles sont utilisées dans des animations. Ces propriétés peuvent entraîner une redistribution et un redessin du navigateur, affectant les performances et la fluidité de la page.

Si vous devez utiliser ces propriétés, réduisez leur utilisation autant que possible. Par exemple, vous pouvez essayer d'utiliser la propriété de transformation CSS3 pour obtenir des effets d'ombre de boîte et de rayon de bordure, car ils tirent mieux parti de l'accélération matérielle du navigateur.

Par exemple, voici un exemple utilisant la propriété box-shadow :

.box {
  box-shadow: 0 0 10px rgba(0, 0, 0, 0.5);
}

L'attribut box-shadow ajoutera un effet d'ombre autour de l'élément, mais cela affectera les performances car le navigateur doit effectuer des calculs et un rendu complexes. Pour optimiser les performances, nous pouvons utiliser la propriété CSS3 transform pour obtenir le même effet :

.box {  transform: translateZ(0);  box-shadow: 0 0 10px rgba(0, 0, 0, 0.5);}

Cet attribut de transformation permet l'accélération matérielle, améliorant ainsi les performances. En même temps, nous pouvons toujours utiliser la propriété box-shadow pour ajouter un effet d’ombre.

3.3 Évitez d'utiliser des sélecteurs complexes

Il existe une certaine relation entre les sélecteurs et les animations. Dans les animations CSS, plus la complexité du sélecteur est élevée, plus le calcul du style est long. L'utilisation de sélecteurs complexes dans les animations entraînera un temps de calcul du style plus long pour le navigateur, ce qui affectera les performances et la fluidité de l'animation.

Par exemple, lorsque nous utilisons des sélecteurs complexes pour sélectionner des éléments et leur ajouter des effets d'animation, le navigateur met plus de temps à calculer le style, affectant ainsi les performances et la fluidité de l'animation. En revanche, lorsque nous utilisons des sélecteurs simples pour sélectionner des éléments et les animer, le navigateur peut calculer les styles plus rapidement, améliorant ainsi les performances et la fluidité des animations.

Disons que nous avons une liste contenant plusieurs éléments. Nous souhaitons ajouter une animation simple à ces éléments, où la couleur d'arrière-plan de l'élément deviendra bleue lorsque la souris passera dessus. Nous pouvons utiliser le code CSS suivant pour obtenir cet effet :

/* 使用类选择器来选择所有项目 */
.item {
  background-color: #fff; /* 初始背景色为白色 */
  transition: background-color 0.3s ease; /* 添加背景色渐变动画 */
}


/* 当鼠标悬停在项目上时,将背景色渐变为蓝色 */
.item:hover {
  background-color: #007bff; /* 背景色渐变为蓝色 */
}

Dans cet exemple, nous utilisons un sélecteur de classe pour sélectionner tous les éléments et leur ajouter une couleur d'arrière-plan initiale et une animation de dégradé de couleur d'arrière-plan. Lorsque la souris survole un élément, nous utilisons : le sélecteur de pseudo-classe de survol pour sélectionner l'élément actuellement survolé et dégradé sa couleur d'arrière-plan en bleu.

Le sélecteur dans cet exemple est très simple et le navigateur peut calculer rapidement le style, ce qui améliore les performances et la fluidité de l'animation. En revanche, si nous utilisons des sélecteurs complexes pour sélectionner des éléments et leur ajouter des effets d'animation, le navigateur mettra plus de temps à calculer le style, affectant ainsi les performances et la fluidité de l'animation.

3.4 Utiliser Will-Change

Utilisez l'attribut will-change pour indiquer au navigateur quels éléments seront animés afin que le navigateur puisse optimiser à l'avance.

L'attribut will-change est un nouvel attribut de CSS3. Il peut indiquer au navigateur quels éléments seront animés, afin que le navigateur puisse optimiser à l'avance et améliorer les performances et la fluidité de l'animation.

Par exemple, si vous souhaitez animer un élément, vous pouvez ajouter le code suivant en CSS :

#textbox {
  opacity: 1; /* 初始透明度为1 */
  transition: opacity 0.3s ease; /* 添加透明度渐变动画 */
  will-change: opacity; /* 告知浏览器我们将会修改透明度 */
}

Dans cet exemple, nous utilisons l'attribut will-change pour indiquer au navigateur que nous allons modifier la transparence de la zone de texte, afin que le navigateur puisse l'optimiser à l'avance. Lorsque l'animation démarre, le navigateur a déjà préparé les ressources correspondantes, afin que l'animation puisse être rendue plus rapidement et que les performances et la fluidité de l'animation puissent être améliorées.

Il convient de noter que l'attribut will-change doit être utilisé avec prudence car il peut amener le navigateur à allouer de la mémoire et des ressources supplémentaires à l'avance, affectant ainsi les performances de la page. Par conséquent, l’attribut will-change ne doit être utilisé que lorsque cela est nécessaire.

CSS3 will-change est une propriété standard du Web et est pris en charge par Chrome/FireFox/Opera en termes de compatibilité.

09cca131ecddd26dfa6e1baa2fd80e8a.png

L'utilisation de l'attribut will-change est l'une des techniques importantes pour optimiser les animations CSS, ce qui peut améliorer les performances et la fluidité des animations.

3.5 Utilisation de requestAnimationFrame

requestAnimationFrame est utilisé à la place de setTimeout ou setInterval pour effectuer des animations car il tire le meilleur parti des optimisations du navigateur.

requestAnimationFrame est une API fournie par le navigateur, qui nous permet d'effectuer une animation avant le prochain tirage du navigateur. Par rapport à setTimeout ou setInterval, requestAnimationFrame peut mieux tirer parti de l'optimisation du navigateur, améliorant ainsi les performances et la fluidité des animations.

Par exemple, si vous souhaitez animer un élément, vous pouvez utiliser requestAnimationFrame pour effectuer l'animation :

function animate() {
  // 更新元素的样式
  element.style.transform = 'translateX(100px)';


  // 使用requestAnimationFrame执行下一帧动画
  requestAnimationFrame(animate);
}


// 开始执行动画
requestAnimationFrame(animate);

Dans le code ci-dessus, nous utilisons requestAnimationFrame pour effectuer une animation. Dans chaque image d'animation, nous mettons à jour le style de l'élément, puis utilisons requestAnimationFrame pour effectuer l'image d'animation suivante. Cela peut tirer le meilleur parti de l’optimisation du navigateur et améliorer les performances et la fluidité de l’animation.

Il convient de noter que requestAnimationFrame n'est pas pris en charge par tous les navigateurs, la compatibilité doit donc être gérée lors de son utilisation. Normalement, nous pouvons utiliser un polyfill pour obtenir la compatibilité requestAnimationFrame.

3.6 Évitez d'utiliser JavaScript pour manipuler le DOM dans les animations

L'utilisation de JavaScript pour manipuler le DOM dans les animations affectera les performances, principalement parce que la manipulation du DOM nécessite beaucoup de ressources car elle provoque une redistribution et un redessin. Chaque opération sur le DOM amènera le navigateur à recalculer la disposition des éléments et à redessiner les éléments. Ces opérations consommeront beaucoup de ressources CPU et de mémoire, provoquant le blocage ou le flou de l'animation.

Dans les animations, si le DOM doit être manipulé fréquemment, cela entraînera des problèmes de performances. Par exemple, si JavaScript est utilisé dans une animation pour modifier la position, la taille, le style et d'autres attributs des éléments, les opérations DOM seront déclenchées, affectant la fluidité de l'animation.

Si vous devez utiliser JavaScript pour manipuler le DOM, réduisez leur utilisation autant que possible. Par exemple, vous pouvez mettre en cache les éléments sur lesquels vous devez opérer dans des variables avant le début de l'animation, puis utiliser ces variables directement pendant l'animation au lieu de retrouver les éléments à chaque fois.

De plus, vous pouvez également utiliser les propriétés d'animation CSS3 pour faire fonctionner le DOM au lieu de JavaScript. Par exemple, vous pouvez utiliser l'attribut d'animation pour obtenir des effets d'animation complexes sans utiliser JavaScript pour faire fonctionner le DOM. Ce qui suit explique en détail pourquoi il est préférable d'utiliser l'animation CSS au lieu de l'animation JavaScript.

3.7 Utilisez des animations CSS et essayez de ne pas utiliser d'animations JavaScript

Parce que les premiers peuvent mieux profiter de l’optimisation du navigateur.

Disons que nous avons un bouton et que lorsque l'utilisateur clique sur le bouton, nous souhaitons supprimer une zone de texte de l'écran et ajouter une animation simple lorsqu'elle est supprimée. Nous pouvons utiliser le code JavaScript suivant pour obtenir cet effet :

var textbox = document.getElementById('textbox'); // 获取文本框元素
var button = document.getElementById('button'); // 获取按钮元素


button.addEventListener('click', function() {
  textbox.style.opacity = 0; // 文本框透明度渐变为0
  setTimeout(function() {
    textbox.parentNode.removeChild(textbox); // 移除文本框元素
  }, 300); // 延迟300毫秒后移除文本框元素
});

Dans cet exemple, nous utilisons JavaScript pour manipuler les éléments DOM en récupérant les éléments de zone de texte et de bouton, en réduisant progressivement la transparence de la zone de texte à 0 lorsque vous cliquez sur le bouton, puis en supprimant l'élément de zone de texte après 300 millisecondes.

Cependant, cette approche entraîne une redistribution et un redessin du navigateur, ce qui affecte les performances et la fluidité de l'animation. Au lieu de cela, nous pouvons utiliser la propriété de transition CSS3 pour implémenter un effet d'animation simple sans utiliser JavaScript pour manipuler les éléments DOM.

Par exemple, nous pouvons utiliser le code CSS suivant pour implémenter un effet d'animation simple qui fait disparaître progressivement la zone de texte lorsque l'utilisateur clique sur le bouton :

#textbox {
  opacity: 1; /* 初始透明度为1 */
  transition: opacity 0.3s ease; /* 添加透明度渐变动画 */
}


#textbox.hide {
  opacity: 0; /* 透明度渐变为0 */
}

Dans cet exemple, nous utilisons la propriété de transition CSS3 pour implémenter une simple animation de dégradé de transparence. Lorsque l'utilisateur clique sur le bouton, nous utilisons JavaScript pour ajouter une classe de masquage à la zone de texte. Cette classe réduira progressivement la transparence de la zone de texte à 0, obtenant ainsi l'effet d'animation de la zone de texte qui disparaît progressivement.

L'effet d'animation dans cet exemple peut être directement appliqué aux éléments DOM sans utiliser JavaScript pour faire fonctionner les éléments DOM, améliorant ainsi les performances et la fluidité de l'animation.

L'utilisation d'animations CSS dans les animations permet de mieux tirer parti de l'accélération matérielle du navigateur, améliorant ainsi les performances et la fluidité des animations. En comparaison, les animations JavaScript nécessitent généralement plus de calculs et d'opérations, ce qui affecte les performances et la fluidité de l'animation.

Bien entendu, dans certains cas, des animations JavaScript peuvent être nécessaires. Par exemple, dans les animations qui nécessitent une interaction de l'utilisateur, les animations JavaScript peuvent offrir un meilleur contrôle sur le comportement de l'animation. Cependant, dans ce cas, nous devrions toujours réduire autant que possible le nombre d’opérations JavaScript pour améliorer les performances et la fluidité de l’animation.

4. Conclusion

L'animation donne à la page une expérience visuelle riche. Nous devrions essayer d'éviter d'utiliser des propriétés qui déclenchent le relais et la repeinture pour éviter les pertes d'images. Il est préférable de déclarer l'animation à l'avance, afin que le navigateur puisse optimiser l'animation à l'avance. Grâce à l'implication du GPU, les meilleurs attributs désormais utilisés pour l'animation sont les suivants : * opacité * traduction * rotation * échelle, optimisation Javascript, réduction du Layout et du Paint. J'espère qu'il sera utile à tout le monde de comprendre le mécanisme de rendu du navigateur et le développement quotidien des animations.

L’optimisation des performances est une affaire continue et approfondie. Nous avons considérablement optimisé les performances des pages grâce aux mesures d'amélioration présentées dans cet article et obtenu de bons résultats. À l'avenir, nous continuerons à approfondir les domaines qui peuvent être améliorés sur cette base et à proposer des solutions générales à l'avenir.

[Lecture recommandée]

82294785a7505f4d8a38d912c142d291.jpeg

 Compte public « Ctrip Technology »

  Partager, communiquer, grandir

Je suppose que tu aimes

Origine blog.csdn.net/ctrip_tech/article/details/131118259
conseillé
Classement