CSS Variable Performance Issues

2021-04-04

Intro

CSS variables are probably one of the best features which came to CSS recently. They existed in all the preprocessors like SASS/SCSS/LESS etc. for ages. But they were limited to build time. With CSS variables you can actually have it at runtime.

About Performance

If you are familiar with rendering performance you might know that you should always try to keep your rendering at composite level. Meaning that CSS will be applied with transforms that are fast to compute on GPU. What this means in practice is that you are limited to opacity and transform pretty much, to do any animations.

Recently I was working with TailwindCSS. Where CSS variables are used for animations. What I’ve realised is that even simple animation with opacity and transition is less performant than it should be. It’s not an issue with TailwindCSS, more of an issue with how CSS variables work.

How it manifests in TailwindCSS?

Using the following class name from TailwindCSS for animating a drawer.

-translate-x-full

TailwindCSS sets CSS variable which triggers style.

initial click profile “With css vars”

The red block shows 30ms, for animating the drawer. Thing is, our budget is about 16ms, but realistically, about 10-14ms.

This is happening since we would be using .transform which using --tw-translate-y variable. And setting .-translate-x-full changes it.

Solution?

A bit less fancy and maintainable, but still manageable is to use the class name, which will modify opacity and/or transform.

aside {
    transform: translateX(-100%);
}

.open-drawer {
    transform: translateX(0);
}

no css vars profile

So, simply swapping from using CSS variables to regular class names already did have about 30% improvement 🎉. We are still hitting the style layer, but at least it’s within norms.

Final Words

CSS variables are definitely opening up a lot of doors for how we structure our code. But we will probably need to wait a bit for engines to optimize then enough. So if using them, do run performance tests, especially for dynamically changing ones. If updating them often it would have a massive performance hit.