39

Does anyone have cheats or tips for how to improve the smoothness of CSS3 animation? I'm sliding the entire page to the left using a css transition and it's a bit more juttery than I'd like. It's a single element but it contains numerous rounded corners, gradients, drop shadows, etc as it's a complicated page.

In flash actionscript, there is a handy property cacheAsBitmap which converts the animating element into a bitmap before the animation begins. This is a godsend and significantly speeds up certain types of animation. Is there anything like this for CSS? Are there any other tips out there to improve performance without simplifying the page design? I'm thinking things like enabling hardware acceleration or flagging the animation as high priority for the browser.

cronoklee
  • 6,482
  • 9
  • 52
  • 80

4 Answers4

42

Before the will-change directive, you couldn't do this in the same literal way that you can in other languages. The browser (or at least Webkit) dealt with rendering the page by drawing various layers. It should in theory be intelligent enough to work out the layers for you, but sometimes it was a good idea to force something into its own layer.

Sometimes that worked, sometimes it didn't, depending on exactly what's going on.

Anyway.

In CSS, one way to force something into a layer is to transform it using a 3D transform. A common strategy is to add either:

transform: translateZ(0);

or the equivalent:

transform: translate3d(0,0,0);

or the slightly crazy:

transform: rotateZ(360deg);

or the translate ones combined with:

-webkit-backface-visibility: hidden;
-webkit-perspective: 1000;

if things are flickery.

These create a new layer as that's what the spec defines. From http://www.w3.org/TR/css3-transforms/#transform-property,

"Any value other than ‘none’ for the transform results in the creation of both a stacking context and a containing block."

These all need careful testing, and aren't something to just always bung on anything that might need it – sometimes it's better, sometimes it's no different, and sometimes it's worse!

Good luck!

Community
  • 1
  • 1
Rich Bradshaw
  • 71,795
  • 44
  • 182
  • 241
  • Looks interesting, thanks Rich. Are these all different? I mean if the `transform: translateZ(0);` has no effect, is there any point in trying the others? – cronoklee Sep 28 '12 at 16:06
  • 1
    Most of these don't seem to matter anymore as of Chrome 21+ and Firefox 14+. I have noticed that they will actually DEGRADE visual quality in some cases, particularly Chrome, because it switches font rendering from using the OS rendering scheme to something that is GPU-controlled - often leading to jagged edges or unclear fonts reminiscent of IE7 / IE8 bugs when applying filters. – Joshua Sep 28 '12 at 16:07
  • I agree, some times these make things better, sometimes worse. It really depends on exactly what you are doing. The browser is really supposed to be able to make the best decision, so by doing this you are really forcing behaviour that may or not be a good thing! Regarding trying them all, occasionally people report success with one over the other, I'd try them all, but remember you've done it so you can remove it it if it ever looks worse! – Rich Bradshaw Sep 28 '12 at 17:54
  • using chrome 27, on a project with many nodes on a page. This had a huge impact. Perhaps larger sites need to be told what layers to make. a best use scenario for these techniques would likely be if you have many nodes on a single scope level and only some have animations. – Chris Jun 22 '13 at 23:57
  • 4
    The `will-change` is now the recommended way to approach this topic. – Rich Bradshaw Jan 26 '15 at 20:47
32

Since

  • Chrome 36
  • Firefox 38
  • Opera 30
  • Android Browser 40
  • Chrome for Android 42

you can use will-change to inform the browser to prepare for hardware accelerating elements.

.drawer {
    will-change: transform;
}

The will-change property allows you to inform the browser ahead of time of what kinds of changes you are likely to make to an element, so that it can set up the appropriate optimizations before they’re needed, therefore avoiding a non-trivial start-up cost which can have a negative effect on the responsiveness of a page. The elements can be changed and rendered faster, and the page will be able to update snappily, resulting in a smoother experience.

For more information, you can read the full article of that quote.

Marc Dingena
  • 556
  • 5
  • 19
5

From what I've read, drop shadows are one of the biggest performance hits at the moment. You could try adding/remove a class at the start/end of the animation to disable all the shadows for a moment, and fade them back in after the movements.

Brian
  • 2,819
  • 4
  • 24
  • 30
5

Unfortunately this is limited by a number of things, many which you cannot control:

  • Browser performance - all browsers behave differently with CSS3 and Javascript. I have found Safari to be among the best (surprisingly?) in terms of CSS3 rendering performance, with Chrome in second and Firefox in 3rd.
  • GPU performance - Some browsers now offload animation & transition operations to the GPU, in which case the speed / performance is limited by the GPU. If you're on an Integrated Intel GPU, it's not likely to be very smooth compared with a discrete NVIDIA or AMD graphics card.
  • CPU performance - For situations where browsers do NOT offload to GPU, the CPU is used in which case your CPU becomes the bottleneck.
  • Number of other tabs / windows open - many browsers share processes across tabs, and other animations or CPU-consuming operations happening in other tabs / browsers could create performance degredation.

The best way to improve performance currently is to limit the number of things that are being animated / transitioned all at once.

Joshua
  • 3,615
  • 1
  • 26
  • 32