← Back to context

Comment by cluckindan

15 hours ago

Welp, time to make a @function preprocessor. There is no reason for every single client to recalculate things which could have been completely or partially calculated at build time.

I used to share this sentiment (and I’m a web performance consultant by profession so very few people care about performance as much as me!), but when you consider how much calculation we _happily_ let our JS do at runtime, I don’t think forcing CSS to be static/preprocessed is worth it. And that’s not even me taking a swipe at overly-JSsed front-end; I’m talking about any runtime work that JS picks up.

Is preprocessed CSS faster? Yes. Is it meaningfully faster? Probably not.

  • An optimisation I've always wondered about for transforming/translating/animating elements: is it faster to use JS translations or animation API directly on the element (e.g. style.transform / element.animate), or updating CSS variables with JS to let the CSS engine reposition inheriting elements?

    In the context of animations, I'd intuit the latter but would be open to hearing why.

    • You want CSS transitions or animations, since they can run on the compositor thread (most of the time). Zero jank.

      (I work with CSS browser performance, although animations is not my primary field)

    • jQuery has .animate() which uses the JS API and used to be very popular. When CSS Animations became available, that part of jQuery became obsolete overnight.

But there are also plenty of use cases where recalculation will be valuable in the client. CSS variables cascade so a preprocessor isn't going to be able to know ahead of time what any given variable value is.

  • Sure, the new syntax allows doing some nifty stuff with the cascade. In practice, however, I foresee most usage being simple one-time transformations of design tokens. I suppose it is more of a theme architecturing issue.

    • It’s the same with Custom Properties. There are plenty of situations where they are useful at runtime, but a lot of their use is just a single definition on :root, and people really would be better served by the likes of Sass variables, because they foil all kinds of optimisations. You end up with things like color-mix(in srgb, var(--some-unreasonably-long-name), transparent) where it could have just been #1234567f. Quite apart from the runtime and memory costs, bundle size (even gzipped size) can frequently be reduced drastically by flattening eligible variables.

It's a tradeoff. I expect this to be non-trivial, do nothing in the general case (when referring to runtime CSS vars) and possibly increase your final CSS size for any sufficiently complex codebase when unrolled.

CSS is becoming a programming language and not just a style sheet. Don't worry about performance, soon you'll be able to run assembly in it.

  • Yet recently I couldn't find a way to count cousin elements using has and nth-of-type. JS still is needed when use case gets a little complex.