CSS Animation: Use ‘transform’

TL;DR

Vicky Leong
Jun 10 · 2 min read

When animating an element via CSS, prefer modifying transform properties to others for a robust result.

When I first learned to animate with CSS, I learned to do it by changing some properties of an element. For example, let’s animate a square by animating its ‘left’ attribute:

Animating an element by modifying its ‘left’ attribute

Pretty simple, right?

What I didn’t know was that CSS animation is run on the browser’s main UI thread, which is the same thread used to run other things like JS execution and other rendering.

So what happens if we run the same animation as above but, this time, we purposefully trigger a JS execution that would clog that thread?

Click the button in the pen below.

Notice that when the browser is busy executing JS, our animation appears to be broken. The browser doesn’t have enough time to play our animation until the JS function is finished, which will resume the animation.

As you can imagine, this could result in a bad user experience. If we have a CSS loader that relies on that method, and you’re either running a long JS task in the background or creating a ton of DOM elements, our users would see a frozen screen (the loader freezes). Thanks to the single-threaded nature of the browser engine.

While there are certainly ways to improve the real performance offenders (by optimizing our JS and limiting/optimizing DOM creation), we can improve the perceived performance by making our loader animation non-freezable.

The one CSS property change that is not run in the main thread is the transform. Modern browsers will run that animation in a separate thread so that it doesn’t get frozen/blocked by a busy main thread.

Therefore, if we could implement the same kind of animation but with modifying transform instead of left, blocking the main thread should not freeze our animation. Let’s give it a try:

Click the button in the pen below.

That’s it! Our animation is no longer at the mercy of the main thread.

Older browsers may not run transform animation on a separate thread. If you’re supporting them, you may need to find another solution.

You could be in a situation where you’re animating a property that’s not transform-able, e.g. background-color. In that case, you have to get creative or consider changing the animation altogether to something that alters shape, position, or size.

Vicky Leong

Written by

Becoming a better front-end engineer one day at a time.