Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CSS3 animations and transitions - are browsers better at animating graphic backgrounds or DOM elements?

I'm working on a web app; one of it's design requirements is several large CSS3 animations.

Specifically - it have a large <div> that will be transitioned around the screen in response to user input.

Because of the way the app is designed, the "content" of that <div> could be implemented as a large static graphic (e.g., .jpg or .png) set as the <div>'s background.

Or, the content could also be implemented with standard HTML. (The content layout itself is a "little" tricky - it'd require several floated or positioned nested div elements and spans, but nothing crazy.)

My question is - which option is likely to result in the best (smoothest) animations?

(I can obviously test this myself, but it's often hard to judge the smoothness of an animation, especially across a dozen different browsers on a wide range of devices. I also realize that there are other considerations - e.g., maintenance. But in this case, I'm focused entirely on animation performance.)

I'm wondering if browsers are generally better at animating/rendering simple DOM elements WITH graphic backgrounds, or more complex DOM elements (with lots of children) WITHOUT graphic elements?

Also - are there other guidelines? E.g.,

  • Do browsers animate certain types of graphic elements better than others? (E.g., .png vs .jpg)
  • Do browsers animate an element better when it's child elements have position:absolute, when the child elements are floated, or when the child element's positions are determined by the regular document flow?
  • Do things like opacity, drop-shadow, or 3D transforms on nested elements adversely impact animation of the parent element?
  • Does animation performance degrade in relation to the complexity of the element? E.g., does an element with a dozen levels of nested DOM elements animation less smoothly than a simple element with just a text node?

I have an intuition about these things (deeply nested DOM elements will animate less smoothly than a simple element), but my intuition is often wrong. So, I'm wondering if there are "rules" about what's more or less work for the browser.

What else should I consider when large elements with lots of child elements are animated?

like image 594
mattstuehler Avatar asked Nov 04 '22 02:11

mattstuehler


1 Answers

Your answers will depend on the specific rendering strategy used by each implementation, but if you are OK with using WebKit's strategy as the "general" strategy then all your answers lie in this document:

http://www.chromium.org/developers/design-documents/gpu-accelerated-compositing-in-chrome

Webkit Tree Structures

First a "RenderObject" clone of the DOM Tree is created

After this, the tree is traversed and each RenderObject is either incorporated into the RenderLayer of their closest ancestor OR into a new RenderLayer if one of these is true about the RenderObject:

  • It's the root object for the page
  • It has explicit CSS position properties (relative, absolute or a transform)
  • It is transparent
  • Has overflow, an alpha mask or reflection
  • Has a CSS filter
  • Corresponds to <canvas> element that has a 3D (WebGL) context or an accelerated 2D context
  • Corresponds to a <video> element

After this, the tree is traversed and each RenderLayer is either incorporated into the GraphicsLayer of their closest ancestor OR into a new GraphicsLayer if one of these is true about the RenderLayer:

  • Layer has 3D or perspective transform CSS properties
  • Layer is used by <video> element using accelerated video decoding
  • Layer is used by a <canvas> element with a 3D context or accelerated 2D context
  • Layer is used for a composited plugin
  • Layer uses a CSS animation for its opacity or uses an animated webkit transform
  • Layer uses accelerated CSS filters
  • Layer has a descendant that is a compositing layer
  • Layer has a sibling with a lower z-index which has a compositing layer (in other words the layer is rendered on top of a composited layer)

So knowing how this generally works and going on a hunch here I would have to say first minimize things that lead to the creation of a new GraphicsLayer then after that minimize things that lead to the creation of a new RenderLayer. You can probably get away with a good amount of DOM node nesting or whatever you were talking about as long as the extra nodes aren't leading to creations of new RenderLayers or GraphicsLayers.

Also regarding your idea about sending over bitmap images of DOM element vectors instead of the vectors themselves. I really doubt it would faster. It just doesn't make any sense to me that a PNG or a JPEG would somehow be a more efficient way to represent DOM nodes than vectors. But hey I didn't code Webkit so I guess the only way to really know is to profile it.

like image 165
Amann Malik Avatar answered Nov 09 '22 06:11

Amann Malik