blakeembrey / free-style

Make CSS easier and more maintainable by using JavaScript
MIT License
707 stars 29 forks source link

Performance question #4

Closed necolas closed 6 years ago

necolas commented 9 years ago

Have you done any performance profiling for the current strategy? For example, I'm curious how expensive it is to replace the whole contents of the style element for a large app.

blakeembrey commented 9 years ago

I assume you're more interested in dynamic changes with navigation like https://github.com/blakeembrey/react-free-style? This library doesn't really handle any replacing on style dynamically, but I even with the React version I haven't done any in-depth testing. Do you have any ideas on how we could put together a decent test?

ai commented 9 years ago

I think replacing <style> is not a most often operation. Changing between preset states is much more often behaviour, that dynamic style generation. And changing preset state wil be very fast in FreeStyle — just change class in component.

blakeembrey commented 9 years ago

Theoretically free-style is as fast as using plain CSS or inline styles. Perhaps even faster with the smaller selector footprint. All stringification happens outside the render loop and the only activity happening for render changes is either the class name, or, potentially (given the project, e.g. react-free-style), <style /> changes when a style is added or removed entirely. The CSS strings themselves are always cached and not generated dynamically, unless you create the style objects inside render.

Given that, it would be still be really cool to have a realistic benchmark. Perhaps even on page with a timer with simplistic navigation.

namuol commented 9 years ago

There could be some compelling reasons to improve the runtime performance of altering the stylesheets generated by free-style.

I'm currently experimenting (very unscientifically) with dynamically-generated styles in a way that feels more like Radium from the developer point of view.

I find Radium's interface appealing, but their implementation leads to a number of problems that FreeStyle addresses elegantly with ordinary CSS.

Here's a repo with an experimental Radium-like interface to react-free-style: https://github.com/namuol/react-dynamic-styles-experiment

Of course, this doesn't scale as it is implemented right now, since I'm effectively re-generating the entire page's stylesheet any time a new style appears.

However, this approach has some noteworthy benefits:


I find this interface compelling, and believe the performance problems are addressable, so I might attempt to hack together something designed from the ground up to be more dynamic and see if I can get the performance to be acceptable with very large (1000+ rule) stylesheets.

Thoughts?

necolas commented 9 years ago

I ended up experimenting with a way of hijacking use of the style prop and limiting the total size of the CSS to the number of unique declarations: https://github.com/necolas/react-web-sdk. Build-time extraction would be better, but the interface is there.

blakeembrey commented 9 years ago

@namuol @necolas Thanks for the links, I'm definitely going to spend some time reviewing all the ideas being presented. I like the merging of common styles down to the rule level - do you have any statistics on style size output?

I went for the middle ground in the rewrite at #6, where all styles that are duplicates are merged (at any level - e.g. @-rules, root, etc.) - but one unique selector is generated to reference them all and styles now have multiple selectors. Outputting multiple CSS classes like you do for the different levels could be another approach which would be interesting to compare output size.

necolas commented 9 years ago

The precomputed library I am using is under 5 KB gzipped. Some stats from cssstats.com:

114 Properties 594 Unique Declarations (includes vendor prefixes) 419 Rules 433 Selectors 604 Declarations

Comparison with twitter.com (which is an extreme case):

138 Properties 2,152 Unique Declarations 3,095 Rules 4,635 Selectors 6,826 Declarations

The number of properties is very similar (bounded quantity), the number of unique declarations on twitter.com (although excessive) is far smaller than the number of rules, selectors, or declarations.