Subscribe on changes!

Improve CSS performance

avatar
Oct 25th 2021

Hi, @yyx990803

What problem does this feature solve?

There is evidence that styling (CSS) performance is suboptimal in Vue. Most developers rightfully use scoped css. There are multiple ways to achieve scoped css, one being shadow DOM however Vue use the approach of automatically transforming scoped CSS classes/rules into the same class but to which is appended an attribute selector, e.g .example become .example[data-v-f3f3eg9] I was wondering wether using shadow dom instead would provide better performance and I found https://nolanlawson.com/2021/08/15/does-shadow-dom-improve-style-performance/ Shadow DOM can be significantly faster for rich selectors and especially, it seems that attribute selectors are kind of a worst case scenario performance wise and as such I think that this automatic translation strategy by Vue (into attribute selectors) should be reconsidered.

There is in fact a third way, the strategy chosen by Svelte, AKA to generate a class that act as an identifier. https://github.com/sveltejs/v2.svelte.dev/blob/master/content/guide/03-scoped-styles.md More on how they do it here And an update This should, at least, according to this blog, leads to significantly better performance than the current Vue strategy and I think that such a critical path (style resolution) is important performance wise.

Ideally one would benchmark the changes in order to test the theory. Supporting shadow dom is interesting but is a more invasive approach than generating classes, as such it could be supported as an optional strategy but probably not as a default strategy.

What does the proposed API look like?

No user facing change in API needed, (we could support a css attribute shadow-dom-scoped, or even attribute-scoped, if the old behavior was desired)

other style related optimizations?

modern CSS has come a long way and enable major optimizations. The most significant CSS optimization that can be achieved automatically would be for Vue to automatically apply CSS contain to all elements, or at least all containers, or at least all divs. Contain give strong guarantees to the browser, that any sane project should follow and I think Vue would make a big move regarding state of the art performance, and ecologicalness by autoinserting this constraint that should be mandatory anyway in a sane world. As for the differences (overflows being hidden), a way to make them visible to the user would be to only enable css contain on production and not on debug, that way devs could see the difference. There might be many other ways to sanitize for overflows, e.g Vue or the Vue devtools could autorun a JS check for all elements periodically to detect if they overflow, and if so, signal it to the user Given that CSS contains can makes some renderings 1000X fasters, I think it is worth thinking about those tradeoffs and strategies to mitigate overflows (but anyway they are no longer much of a big deal since css contain make them necessarily inexistant (overflow being clipped) Note that while it would make sense to auto enable such a containment policy on new Vue projects, it would be too much of a breaking change for existing projects.

There are other css properties that could be considered to be injected by Vue in order to improve performance, for free, for all users. E.g possibly will-change?

There are also techniques that are not related to CSS rules, such as the order of inclusion in the document, the method of inclusion, the use of prefecthing/lazy/preload or auto-inlining and assembling the critical CSS related > CSS files can block the page load and delay the rendering of your page. Using preload can actually load the CSS files before the browser starts showing the content of the page. Some of those optmizations could be made by Vue as smart defaults or at least exposed as optins.

avatar
Oct 25th 2021

When you say there is evidence, people expect you to provide it as well.

Have you faced performance issues due to CSS in the Vue applications you develop? Most of the things (if not all) you mention can already be achieved.

Some of the ideas you mentioned are interesting but they go beyond vue scope (e.g. contain)

avatar
Oct 25th 2021

The evidence is that attribute selectors are a slow path and that Vue scoped styles generate a lot of them and this is avoidable. Source

avatar
Oct 26th 2021

That is about styles shadow dom vs regular dom, it's not about "Vue suboptimal styling performance". Note there is much more that has an impact on performance and that using Shadow Dom comes with other costs. BTW, it's also important to check on the compatibility of features like contain (not supported by any browser).

In any case, this should go in a discussion in the rfcs as it's still at the very early stage of an idea and is making quite a few wrong assumptions about what is missing and what is not in Vue ecosystem.

BTW, we have a Discord server where people can discuss, share, and learn together.