Je me suis récemment lancé dans le Web animation, je vais donc enregistrer mon processus d'apprentissage et le partager avec tout le monde.
Page de démonstration de la rotation planétaire 3D CSS3, veuillez cliquer sur : Démo. (Il est recommandé d'utiliser Chrome pour l'ouvrir)
Le code complet de cet article, ainsi que d'autres effets CSS3, peuvent être vus sur mon Github, et j'espère que vous pourrez lui donner une étoile.
Eh bien, certaines personnes ne pourront peut-être pas ouvrir la démo ou la page est foirée. Voici quelques rendus : (Les images sont un peu grandes, veuillez patienter)
Effet de mouvement planétaire 3D CSS3 Image
Prise au hasard d'une autre capture d'écran : Je vous recommande fortement de cliquer sur la page Démo pour en faire l'expérience. Le charme de CSS3 3D, ce que les images peuvent montrer est après tout limité. Ensuite, le processus de production de cette animation de mouvement planétaire 3D CSS3 ne sera pas décrit en détail. Cet article se concentre sur l'introduction de l'animation Web et l'optimisation des performances. Pour un CSS3 3D détaillé, vous pouvez consulter le blog précédent : [CSS3 Advanced] Perspective rotative 3D sympa. Idée simple :
1. Utiliser le mur de photos 3D réalisé dans l'article précédent comme prototype et le modifier 2. De nombreuses méthodes ont été pensées pour réaliser chaque sphère, et finalement utilisées dans ; Ce compromis, chaque sphère est elle-même une forme 3D CSS3. Ensuite, utiliser Sass pour écrire du CSS pendant le processus de production peut réduire une grande partie du processus fastidieux d'écriture d'animations CSS 3 Dans la démo, Ce qui suit entrera au centre de cet article. Du point de vue de l'optimisation des performances, nous parlerons des principes de rendu et d'affichage du navigateur, du redessin et du réarrangement du navigateur, de l'optimisation de la détection des performances d'animation, etc. : Navigateur Le principe de rendu et d'affichage et son impact sur l'animation web Le sous-titre est un peu gros On sait que les cœurs (moteurs de rendu) des différents navigateurs sont différents, comme le plus grand public. navigateur chrome maintenant Le noyau est le noyau Blink (utilisé dans Chrome (version 28 et ultérieure), Opera (version 15 et ultérieure) et le navigateur Yandex), Firefox est Gecko et IE est Trident. Le noyau du navigateur est responsable de l'interprétation de la page Web. syntaxe et son interprétation Lors du rendu (affichage) des pages Web, les principes de fonctionnement des différents noyaux de navigateur ne sont pas complètement cohérents. Donc en fait, ce dont nous parlerons principalement ci-dessous, c'est le principe de rendu sous le navigateur chrome. Comme il existe de nombreuses informations vérifiables sur le rendu du noyau Chrome, nous n'osons pas tirer de conclusions sur les navigateurs dotés d'autres noyaux. La discussion ci-dessous concerne donc par défaut le navigateur Chrome. Tout d'abord, je souhaite tirer quelques conclusions : Utilisez transDocument Object Model, Document Object Modèle). Lorsque le navigateur affiche une page, il utilise de nombreuses représentations intermédiaires qui ne sont pas exposées aux développeurs, dont la structure la plus importante est la couche.
Cette couche est au centre de cet article : Dans Chrome, il existe différents types de couches : RenderLayer (responsable du sous-arbre DOM), GraphicsLayer (responsable du sous-arbre RenderLayer) . Nous discuterons ensuite de la couche GraphicsLayer. Le calque GraphicsLayer est téléchargé sur le GPU sous forme de texture.La texture ici est très importante Alors,
La texture fait ici référence à un terme GPU : considérez-la comme une image bitmap qui est déplacée de la mémoire principale (telle que la RAM) vers la mémoire d'image (telle que la VRAM dans le GPU). Une fois déplacé vers le GPU, vous pouvez le faire correspondre dans une géométrie de maillage et utiliser des textures dans Chrome pour extraire de gros morceaux de contenu de page du GPU. Il est facile de faire correspondre différentes positions (position) et transformations en appliquant des textures à une grille rectangulaire très simple, c'est ainsi que fonctionne le CSS 3D.
C'est difficile à comprendre. Il suffit de regarder l'exemple dans Chrome, nous pouvons voir le concept de GraphicsLayer — couche mentionné ci-dessus. Dans les outils de développement, nous effectuons la sélection suivante pour faire apparaître l'option Afficher les bordures des calques :
Dans une page très simple, nous pouvons voir que comme indiqué ci-dessous, cette page une seule couche. La grille bleue représente les tuiles. Vous pouvez les considérer comme des unités d'un calque (et non comme des calques). Chrome peut les télécharger sur le GPU dans le cadre d'un grand calque :
Comme la page ci-dessus est très simple, aucun calque n'est créé, mais dans une page très complexe par exemple, on peut définir une propriété CSS 3D à l'élément pour le transformer , nous pouvons voir à quoi cela ressemble lorsqu'un élément a son propre calque.
Faites attention à la bordure orange, qui délimite les calques dans cette vue :
Le calque entouré par la bordure jaune dans le diagramme ci-dessus est GraphicsLayer, ce qui est très important pour notre animation Web. Habituellement, Chrome dessine le contenu d'un calque avant de le télécharger sur le GPU sous forme de texture (peinture). ) en bitmap. Si le contenu ne change pas, il n'est pas nécessaire de repeindre le calque.
L'importance de ceci est que le temps passé à redessiner peut être utilisé pour faire d'autres choses, comme exécuter JavaScript. Si le dessin prend beaucoup de temps, cela entraînera également des échecs et des retards d'animation.
Alors quand un élément déclenche-t-il la création d'un calque ? Pour l'instant, les calques seront créés lorsque l'une des conditions suivantes est remplie :
Transformation 3D ou perspective (perspective, transform) Propriétés CSS
utiliser L'élément
avec décodage vidéo accéléré a un contexte 3D (WebGL) ou un contexte 2D accéléré avec l'élément <canvas>
Plug-ins hybrides (tels que Flash)
Faites des animations CSS sur votre propre opacité ou utilisez un élément de transformation animé
Les éléments avec CSS accéléré filtre
les éléments ont un nœud descendant qui contient une couche composite (en d'autres termes, un élément a un élément enfant (l'élément est dans son propre calque)
L'élément a un z-index inférieur et contient un élément frère dans le calque composite (en d'autres termes , l'élément est dans le rendu composite au-dessus du calque)
Pour les pages Web statiques, le calque ne sera pas modifié après avoir été dessiné pour la première fois, mais pour l'animation Web, les éléments DOM de la page changent constamment. Si le contenu du calque change pendant le processus de transformation, le calque sera repeint.
Les puissants outils de développement de Chrome fournissent des outils qui nous permettent de voir quel contenu a été redessiné lors de l'exécution de la page animée :
Dans l'ancienne version In chrome, il existe une option afficher les rects de peinture. Vous pouvez voir quels calques de la page ont été redessinés et marqués d'une bordure rouge.
Mais la nouvelle version de Chrome semble avoir supprimé cette option. L'option actuelle est d'activer le clignotement de la peinture, qui est également utilisée pour identifier les changements dynamiques du site Web et est marquée d'une bordure verte.
En regardant le schéma ci-dessus, vous pouvez voir qu'il y a plusieurs cases vertes sur la page, indiquant qu'un redessin a eu lieu. Notez que Chrome ne redessinera pas toujours l'intégralité du calque, il tentera de redessiner intelligemment les parties invalides du DOM.
Logiquement parlant, avec autant d'animations qui se produisent sur la page, les redessins devraient être très fréquents. Cependant, dans l'animation de ma planète dans l'image ci-dessus, je ne vois que quelques cases de redessin vertes. est le GPU. L'optimisation, la seconde est que si la page d'animation entière n'a qu'un seul calque, alors en utilisant la transformation pour la transformation, la page devra inévitablement être redessinée, mais en utilisant la technologie de superposition (GraphicsLayer), c'est-à-dire les éléments qui se rencontrent. Dans la situation mentionnée ci-dessus, créez leurs propres calques, puis un élément Le calque créé utilise une transformation, telle que la rotation. À ce stade, la transformation de rotation du calque n'affecte pas les autres calques, le calque n'a donc pas nécessairement besoin d'être redessiné. (Avis personnels, veuillez apporter des corrections).
Comprendre le redessinage des calques est essentiel pour optimiser les performances des animations Web.
Qu'est-ce qui cause l'invalidation et le redessinage forcé ? Il est difficile de répondre de manière exhaustive à cette question car il existe un grand nombre de situations qui conduisent à une rupture de frontière. La situation la plus courante consiste à modifier le DOM ou à provoquer une redistribution en manipulant les styles CSS.
La meilleure façon de trouver la cause première des repeintures et des refusions est d'utiliser la chronologie des outils de développement et d'activer l'outil de peinture clignotante, puis d'essayer de trouver l'endroit où le DOM a été modifié juste avant la repeinture/ refusion.
Alors, comment le navigateur s'affiche-t-il depuis les éléments DOM jusqu'à l'animation finale ?
Le navigateur analyse le HTML, obtient le DOM et le divise en plusieurs couches (GraphicsLayer)
Calculez les résultats de style pour les nœuds de chaque couche (Recalculer le style – recalcul du style)
Générer des graphiques et des positions pour chaque nœud (Mise en page – redistribution et relayout)
Convertir chaque nœud Les nœuds sont dessinés et remplis dans le bitmap du calque (Paint Setup et Paint – Redraw)
Le calque est téléchargé sur le GPU sous forme de texture (texture)
Conformez plusieurs calques à la page pour générer l'image d'écran finale (Couches composites – réorganisation des calques)
Une grande partie du coût de l'animation Web réside dans le redessin des calques , avec des calques comme modèle composite sous-jacent a un impact profond sur les performances de rendu. Lorsqu'aucun dessin n'est requis, la surcharge des opérations composites est négligeable. Ainsi, lorsque vous essayez de déboguer des problèmes de performances de rendu, le premier objectif est d'éviter les redessins de calques. Cela fournit ensuite une direction pour l’optimisation des performances de l’animation et réduit le redessinage et la redistribution des éléments.
Ici il faut d'abord distinguer deux notions, reflow et reflow.
Lorsqu'une partie (ou la totalité) de l'arbre de rendu doit être reconstruite en raison de changements dans la taille, la disposition, le masquage, etc. des éléments. C'est ce qu'on appelle la redistribution, qui est le relayage.
Chaque page doit être redistribuée au moins une fois, lors du premier chargement de la page. Pendant la redistribution, le navigateur invalidera la partie affectée de l'arborescence de rendu et reconstruira cette partie de l'arborescence de rendu. Après avoir terminé la redistribution, le navigateur redessinera la partie affectée à l'écran. Ce processus est appelé redessin.
Lorsque certains éléments de l'arbre de rendu doivent mettre à jour les attributs, et que ces attributs n'affectent que l'apparence et le style des éléments, mais n'affecteront pas la mise en page, comme couleur de fond . Cela s’appelle redessiner.
Il convient de noter que la redistribution provoquera certainement un redessinage, mais le redessinage ne provoquera pas nécessairement un reflux.
Évidemment, la refusion est plus coûteuse. En termes simples, la refusion se produit lorsque l'actionnement d'un élément amène l'élément à modifier sa taille ou sa position.
Redimensionner la fenêtre (Redimensionner la fenêtre)
Changer la police)
Ajout ou suppression d'une feuille de style (Ajout ou suppression d'une feuille de style)
Modifications de contenu, par exemple lorsque l'utilisateur saisit des modifications de contenu , comme un utilisateur tapant du texte dans
une zone de saisie)
Activer CSS pseudo-classe , comme :hover (Activation de pseudo classes CSS telles que :hover (dans IE l'activation de la pseudo-classe) classe d'un frère ou d'une sœur))
Manipulation de l'attribut de classe
Un script manipulant le DOM
Calculer le décalageLargeur et le décalage Height propriétés (Calcul de offsetWidth et offsetHeight)
Définir le style La valeur de l'attribut (Définition d'une propriété de l'attribut de style)
Donc pour la page, notre but est de minimiser la redistribution et le redessinage de la page Un simple marron :
// 下面这种方式将会导致回流reflow两次 var newWidth = ap.offsetWidth + 10; // Read ap.style.width = newWidth + 'px'; // Write var newHeight = ap.offsetHeight + 10; // Read ap.style.height = newHeight + 'px'; // Write // 下面这种方式更好,只会回流reflow一次 var newWidth = ap.offsetWidth + 10; // Read var newHeight = ap.offsetHeight + 10; // Read ap.style.width = newWidth + 'px'; // Write ap.style.height = newHeight + 'px'; // Write
Les quatre phrases ci-dessus, parce qu'elles impliquent l'opération offsetHeight, forcent le navigateur à redistribuer deux fois, tandis que les quatre phrases suivantes combinent l'opération offset, donc la redistribution d'une page est réduite.
Réduire la redistribution et le redessin signifie en fait réduire les opérations sur l'arbre de rendu (fusion de plusieurs modifications DOM et de style), réduire les demandes de certaines informations de style et utiliser pleinement la stratégie d'optimisation du navigateur.
En fait, le navigateur lui-même a une stratégie d'optimisation si chaque phrase de Javascript opère sur le DOM, elle le sera. redistribué et redessiné. Si tel est le cas, le navigateur risque de ne pas être en mesure de le gérer. Par conséquent, de nombreux navigateurs optimiseront ces opérations. Le navigateur maintiendra une file d'attente et placera toutes les opérations qui provoqueront une redistribution et un redessinage dans cette file d'attente. Lorsque les opérations dans la file d'attente atteignent un certain nombre ou un certain intervalle de temps, le navigateur La file d'attente. être vidé et un lot sera traité. Cela transformera plusieurs refusions et redessinages en une seule redistribution et redessinage.
Mais il y a des exceptions, car parfois nous avons besoin d'obtenir avec précision certaines informations de style, comme suit :
décalage Top, offsetLeft, offsetWidth, offsetHeight
scrollTop/Left / Largeur/Hauteur
clientTop/Gauche/Largeur/Hauteur
largeur, hauteur
a demandé getComputedStyle(), ou le currentStyle
<🎜 d'IE >
Styles consommateurs de performances
Différents styles ont une consommation de performances différente, par exemple Box- shadow est très gourmand en performances du point de vue du rendu car leur code de dessin prend trop de temps à s'exécuter par rapport aux autres styles. Cela signifie que si un style gourmand en performances doit être redessiné fréquemment, vous rencontrerez des problèmes de performances. Deuxièmement, il faut savoir que rien n’est constant. Un style qui fonctionne mal aujourd’hui peut être optimisé demain, et il existe des différences entre les navigateurs. La clé est donc d'utiliser vos outils de développement pour identifier les goulots d'étranglement en termes de performances, puis de trouver des moyens de réduire la charge de travail du navigateur. Heureusement, le navigateur Chrome fournit de nombreuses fonctions puissantes qui nous permettent de détecter nos performances d'animation. En plus de ce qui précède, nous pouvons également afficher les informations FPS de la page en vérifiant le compteur FPS ci-dessous. Utilisation du GPU :Utilisez will-change pour améliorer les performances de rendu telles que le défilement des pages, l'animation, etc.
La documentation officielle indique , il s'agit encore d'une fonctionnalité expérimentale, donc la syntaxe et le comportement de cette fonctionnalité peuvent changer dans les futures versions du navigateur.使用方法示例:(具体每个取值的意义,去翻翻文档)
will-change: auto will-change: scroll-position will-change: contents will-change: transform // Example of <custom-ident> will-change: opacity // Example of <custom-ident> will-change: left, top // Example of two <animateable-feature> will-change: unset will-change: initial will-change: inherit // 示例 .example{ will-change: transform; }
will-change 为 web 开发者提供了一种告知浏览器该元素会有哪些变化的方法,这样浏览器可以在元素属性真正发生变化之前提前做好对应的优化准备工作。 这种优化可以将一部分复杂的计算工作提前准备好,使页面的反应更为快速灵敏。
值得注意的是,用好这个属性并不是很容易:
不要将 will-change 应用到太多元素上:浏览器已经尽力尝试去优化一切可以优化的东西了。有一些更强力的优化,如果与 will-change 结合在一起的话,有可能会消耗很多机器资源,如果过度使用的话,可能导致页面响应缓慢或者消耗非常多的资源。
有节制地使用:通常,当元素恢复到初始状态时,浏览器会丢弃掉之前做的优化工作。但是如果直接在样式表中显式声明了 will-change 属性,则表示目标元素可能会经常变化,浏览器会将优化工作保存得比之前更久。所以最佳实践是当元素变化之前和之后通过脚本来切换 will-change 的值。
不要过早应用 will-change 优化:如果你的页面在性能方面没什么问题,则不要添加 will-change 属性来榨取一丁点的速度。 will-change 的设计初衷是作为最后的优化手段,用来尝试解决现有的性能问题。它不应该被用来预防性能问题。过度使用 will-change 会导致大量的内存占用,并会导致更复杂的渲染过程,因为浏览器会试图准备可能存在的变化过程。这会导致更严重的性能问题。
给它足够的工作时间:这个属性是用来让页面开发者告知浏览器哪些属性可能会变化的。然后浏览器可以选择在变化发生前提前去做一些优化工作。所以给浏览器一点时间去真正做这些优化工作是非常重要的。使用时需要尝试去找到一些方法提前一定时间获知元素可能发生的变化,然后为它加上 will-change 属性。
使用 transform3d api 代替 transform api,强制开始 GPU 加速
GPU 能够加速 Web 动画,这个上文已经反复提到了。
3D transform 会启用GPU加速,例如 translate3D, scaleZ 之类,当然我们的页面可能并没有 3D 变换,但是不代表我们不能启用 GPU 加速,在非 3D 变换的页面也使用 3D transform 来操作,算是一种 hack 加速法。我们实际上不需要z轴的变化,但是还是假模假样地声明了,去欺骗浏览器。
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!