35

This is a somewhat general question.

Is anybody aware of the effects on performance of using many CSS variables within a given document? Has anybody done any tests?

Does the element to which you associate the variable have any effect on performance? Is performance impeded more so by, say, all variables being assigned to :root than assigning them to the individual blocks of styling where they might only be used?

oldboy
  • 5,729
  • 6
  • 38
  • 86
  • "all variables being assigned to :root than assigning them to the individual blocks of styling where they might only be used?" Yes, this is to be avoided as it does have a kinda big performance impact, especially if you're updating values in a `requestAnimationFrame` or something like that – Zach Saucier Aug 12 '23 at 23:29

2 Answers2

26

Yes there are tests that have been done. Essentially you apply the CSS changes via JavaScript and measure the performance.

You will want to learn about scoping your CSS variables and the number of affected elements. As these numbers increase, so does your draw time.

There is a handy article on this subject at https://lisilinhart.info/posts/css-variables-performance/

TL;DR be aware of style recalculations, since CSS Variables are inheritable — changing a variable on a parent can affect many children prefer using single classes for elements to make style calculations easier for the browser calc() has good performance with variables, but still has problems with browser support with certain units like deg or ms prefer using setProperty rather than inline styles to set CSS variables in JavaScript

And another quote:

Via Javascript the --bg variable was first set on the .container parent element, which resulted in a fairly long duration of 76ms. Then the same variable was set on the first child .el , which only lasted about 1.9ms. So the more children a parent element has using this variable, the more expensive setting a CSS variable on this element gets.

jeffjenx
  • 17,041
  • 6
  • 57
  • 99
  • 1
    FWIW I try to have smooth `transition: transform` (translate, scale, forcing it into GPU with backface/translate3d) of about 600 minuscule sized DOM elements, basically, points. The transition is about 60FPS on my Ipad Air 2. BUT it hangs for 1-2 seconds before the transition even starts. Feels like it takes 1-2 seconds for OOM 1k basic math operations, which is pretty abysmal. This with carefully targeting the ~600 DOM elements (4px4px empty DIVs with background color, ie. points for a HTML scatterplot concept as SVG transition is a no go due to no GPU compositing in webkit or other browsers) – Robert Monfera Apr 12 '20 at 21:52
  • As for targeting elements: CSS is designed with declarative property assignment in mind. Ie. idiomatic CSS tries to be compact, so if there are meaningful abstractions, it's encouraged that appropriate selectors encapsulate this. I'd dislike it if there was advice to the tune of "just inline style each element" as that's no good CSS; takes longer to either download/parse SSR content or run JS. If it's not fast via normal CSS selectors then it means that the dependency graph (DAG) of `calc`s isn't done in a perf conscious way – Robert Monfera Apr 12 '20 at 21:58
  • I also incorrectly assumed that `will-change` helps the browser optimize the `calc`/inheritance/custom prop update DAG such that invariant (non-`will-change` subgraphs) can be "locked in", cached, materialized etc. while the `will-change` prop ie. `transform` and my `--zoomX`, `--zoomY` is cheap to update, which computationally should be, due to trivial node amounts (600 DIV points). Btw. the actual transition tweening is not the key bottleneck, there's user-blocking delay even with immediately applied `transform` change – Robert Monfera Apr 12 '20 at 22:02
10

FWIW, CSS Variables performance benchmark 2021 did some tests with 5000 CSS variables on 10,000 HTML nodes, and it was only 0.7% slower than raw CSS.

jeantimex
  • 1,619
  • 16
  • 14
  • Takeaway from this: The number of CSS variables itself doesn't really have a perf impact. But how you're using them does, especially when you're updating CSS variables often – Zach Saucier Aug 13 '23 at 01:43