Comment savoir (à des fins de test) si l’accélération matérielle a été activée pour une animation CSS?
J’ai le code suivant qui agrandit essentiellement un élément et le rend en plein écran (sans utiliser l’API HTML5 en plein écran). Il fonctionne comme une tortue asthmatique bégayant sur la plupart des mobiles lors de l’utilisation d’une animation jQuery, j’ai donc utilisé CSS3.
Voici l’exemple de jsFiddle:
$("#makeFullscreen").on("click", function() { var map = $("#map"), mapTop = map.offset().top, mapLeft = map.offset().left; $("#map").css({ "position": "fixed", "top": mapTop, "left": mapLeft, "width": map.outerWidth(true), "height": map.outerHeight(true) }); setTimeout(function(){map.addClass("fullscreen")},1); return false; });
.mapContainer { width: 150px; height: 200px; position: relative; margin: 0 auto; } .map { background: #00f; position: absolute; top: 0; left: 0; bottom: 0; right: 0; text-align: center; } .fullscreen { -webkit-transition: top 300ms ease-out, height 300ms ease-out, left 300ms ease-out, width 300ms ease-out; -moz-transition: top 300ms ease-out, height 300ms ease-out, left 300ms ease-out, width 300ms ease-out; -ms-transition: top 300ms ease-out, height 300ms ease-out, left 300ms ease-out, width 300ms ease-out; -o-transition: top 300ms ease-out, height 300ms ease-out, left 300ms ease-out, width 300ms ease-out; transition: top 300ms ease-out, height 300ms ease-out, left 300ms ease-out, width 300ms ease-out; -webkit-transform: translate3d(0, 0, 0); -moz-transform: translate3d(0, 0, 0); -ms-transform: translate3d(0, 0, 0); transform: translate3d(0, 0, 0); top: 0 !important; left: 0 !important; width: 100% !important; height: 100% !important; } #makeFullscreen { margin-top: 20px; } }
Cela ajoute une classe et l’élément passe d’un état à l’autre à l’aide d’une transition CSS. C’est plus rapide que jQuery mais c’est toujours du stuttery sur iOS et Android.
Mais je lis ici que vous pouvez forcer la transition à être accélérée à l’aide du GPU en spécifiant une transformation 3D qui ne fait essentiellement rien, comme ceci:
-webkit-transform: translate3d(0, 0, 0); -moz-transform: translate3d(0, 0, 0); -ms-transform: translate3d(0, 0, 0); transform: translate3d(0, 0, 0);
Cependant, après avoir ajouté cela à mon CSS, je ne constate aucune amélioration visuelle.
Existe-t-il un moyen de savoir si l’accélération matérielle a été activée via les outils de développement de n’importe quel navigateur? Je n’ai pas besoin de détecter cela avec un script, je veux juste savoir à des fins de test.
Une transition de propriété CSS sur un élément est accélérée matériellement si toutes ces conditions sont remplies:
En règle générale, les conditions pour ces conditions sont les suivantes:
opacity
, transform: translate
/ mettre à l’ scale
/ rotate
, etc.) peuvent être accélérées. transform: translate3d
) Pour identifier si cela est activé:
chrome://settings
Si l’accélération est activée, alors:
chrome://gpu
Plus de détails sur le composant logiciel à partir de la documentation :
Dans certaines situations, la composition matérielle est irréalisable, par exemple si les pilotes graphiques du périphérique sont sur liste noire ou si le périphérique manque complètement d’un GPU. Pour ces situations, une implémentation alternative au rendu GL appelée SoftwareRenderer
(Remarque: Chrome dispose également d’un chemin de rendu de logiciel hérité , “toujours en place depuis mai 2014, mais sera bientôt entièrement supprimé de Blink.”)
Voici un excellent article avec plus d’informations: Rendu accéléré dans Chrome .
Si l’accélération est activée, alors:
about:config
layers.acceleration.disabled
Si l’accélération de la couche est activée (si la valeur est false
), alors:
about:support
S’il ne commence pas par 0/
et qu’une API de rendu est affichée (par exemple, OpenGL, Direct3D), l’accélération GPU est active.
defaults write com.apple.Safari IncludeInternalDebugMenu 1
Les seules transitions de propriétés CSS pouvant être accélérées matériellement sont celles qui se produisent à l’étape de composition du processus de rendu. Par exemple:
opacity
transform: translate
et ses amis: translateX
, translateY
, translateZ
, translate3d
transform: scale
et ses amis: scaleX
, scaleY
, scaleZ
, scale3d
transform: rotate
et ses amis: rotateX
, rotateY
, rotateZ
, rotate3d
Pour tirer pleinement parti de l’accélération, aucune propriété non-compositing ne doit être transférée . Par exemple:
transform: translate
peut tirer pleinement parti de l’accélération (car le calque de l’élément peut simplement être recomposé par le GPU). transform: translate
et width
ne tirera presque aucun avantage de l’accélération (car une transition sur la width
entraîne le repeinte du calque de l’élément par la CPU pour chaque image d’animation). Le moteur de rendu du navigateur décide (en fonction des préférences de l’utilisateur, des styles CSS, etc.) de donner ou non son propre calque de composition à un élément.
Par exemple, Chrome a cette liste de raisons et cette option également dans chrome://flags
:
Compositing pour RenderLayers avec transitions
Activer cette option donnera aux RenderLayers une transition d’opacité, de transformation ou de filtrage leur propre calque composé.
Si un élément n’a pas reçu son propre calque, aucune transition CSS sur cet élément ne sera accélérée.
transform: translate3d
( le hack “go plus vite” ) force généralement un élément à se voir atsortingbuer son propre calque.
Mais même si un élément a reçu son propre calque, les transitions sur les propriétés non composites ( width
, height
, left
, top
, etc.) ne peuvent toujours pas être accélérées , car elles se produisent avant l’étape de composition (par exemple, dans les étapes de mise en page ou de peinture ). @ChrisSpittles C’est pourquoi vous n’avez constaté aucune amélioration visuelle après avoir ajouté transform: translate3d
.
La plupart des navigateurs peuvent afficher des bordures colorées autour des couches composites, afin de faciliter leur identification pour le développement / débogage:
L’affichage des bordures des couches composites peut être effectué de l’une des deux manières suivantes:
chrome://flags
et activez les bordures des calques de rendu composite (option “Rend une bordure autour des calques de rendu composés pour faciliter le débogage et l’étude de la composition des calques”). Vous devrez relancer Chrome pour que cela prenne effet. Maintenant, déclenchez la transition CSS sur l’élément. Si elle a une bordure colorée, elle a son propre calque de composition.
Les couleurs de bordure et leur signification sont définies dans debug_colors.cc
. Plus de détails ici et ici .
Pour dessiner les frontières des couches composites:
about:config
layers.draw-borders
et activez-la Maintenant, déclenchez la transition CSS sur l’élément. Si elle a une bordure colorée, elle a son propre calque de composition.
Les couleurs des bordures et leur signification sont définies dans Compositor::DrawDiagnosticsInternal
.
(Cela ne fonctionne pas pour moi avec Safari 7.0.3, mais il semble que cela a fonctionné pour certaines personnes aussi récemment que l’année dernière .)
Lancez Safari depuis le terminal avec la variable d’environnement booléenne CA_COLOR_OPAQUE
définie:
$ CA_COLOR_OPAQUE=1 /Applications/Safari.app/Contents/MacOS/Safari
Méthode alternative:
$ export CA_COLOR_OPAQUE=1 $ /Applications/Safari.app/Contents/MacOS/Safari
Apparemment, les couches à accélération matérielle devraient être colorées en rouge. Plus de détails ici et ici .
Voici une méthode alternative qui fonctionne pour moi dans Safari 7.0.3 (crédit de David Calhoun ):
Maintenant, déclenchez la transition CSS sur l’élément. Si elle a une bordure colorée, elle a son propre calque de composition.
Pour plus de détails, consultez ces excellents articles: