CSS animations off the UI thread

March 12th, 2013. Tagged: CSS, performance

This excellent Google I/O talk mentions that Chrome for Android moves the CSS animations off of the UI thread, which is, of course, a great idea. Playing around with it, here's what I found:

  • Browser support: Desktop Safari, iOS Safari, Android Chrome.
  • You need to use CSS transforms. Animating regular properties doesn't work.

Update: (see comments) confirmed support in IE10. Reported support in Firefox OS too, but I cannot personally confirm

More details and test page below.

Single UI thread

As you probably know the browser is single threaded. Do something heavy in ECMAScript land and everything freezes.

The big idea

CSS animations should be excluded from the "everything" that freezes.

Test page

Here's a test page with some animations. Click the kill button and see what happens.

Animations

The red box that spins is animated like:

.spin {
  animation: 3s rotate linear infinite;
}
 
@keyframes rotate {
  from {transform: rotate(0deg);}
  to {transform: rotate(360deg);}
}

The green one is also animated with a transform:

.walkabout-new-school {
  animation: 3s slide-transform linear infinite;
}
 
@keyframes slide-transform {
  from {transform: translatex(0);}
  50% {transform: translatex(300px);}
  to {transform: translatex(0);}
}

The blue one is animated using the margin-left property, not a transform:

.walkabout-old-school {
  animation: 3s slide-margin linear infinite;
}
 
@keyframes slide-margin {
  from {margin-left: 0;}
  50% {margin-left: 100%;}
  to {margin-left: 0;}
}

Kill switch

The kill button just pegs the CPU in a infinite loop for 2 seconds:

function kill() {
  var start = +new Date;
  while (+new Date - start < 2000){}
}

Results

In non-supporting browsers, which is most of them, the kill switch kills all the animations. Business as usual.

In the supporting browsers (All Safaris and Andriod Chrome) the kill only affects the blue button, the one that animates a CSS property, as opposed to using a CSS transform. But the animations that use a transform keep on going!

Take aways

  1. Rejoice! The future is here! Drink and dance uncontrollably around the campfire!
  2. After you sober up, make sure your CSS animations use transform: where possible
  3. Keep migrating them JS animations to CSS
  4. Bug your browser vendor to support this

Comments? Feedback? Find me on Twitter, Mastodon, Bluesky, LinkedIn, Threads