descartes icon indicating copy to clipboard operation
descartes copied to clipboard

Improve Performance

Open JonHMChan opened this issue 9 years ago • 5 comments

This is currently the achilles heel in using this library in a production environment. CSS (and the Less, and Sass that can generate it) get all the advantages of being optimized for the browser. Using just JavaScript here means Descartes can't exploit any of those optimizations: how can we improve the performance here? Here are a few ideas and considerations:

  • Generate a stylesheet. Descartes could generate CSS just like other preprocessors so that basic styles can be cached, served, and rendered. The major issue is making sure that Descartes could accurately do so because of dynamic values: since it uses inline styling and actually does style calculation at the node level, it's more specific than traditional CSS would be.
  • Fine tune the code. This should happen anyways, but I have a comparatively naive understanding of JavaScript performance where others in the OS community could really contribute. The library is highly recursive, requires a lot of O(n) run throughs multiple times, and doesn't take full advantage of some of JavaScript's concurrency or caching capability. The more ideas, the better.
  • Eat the cost. Maybe I'm overthinking this? What is really the cost of speed here? Is the flexibility provided by the library to do event-based, highly context-based, and largely cascade free styling worth the cost of performance? In Less and Sass (which also have similar JS libraries that compute style at load time) the cost is not justified because it's mainly used for debugging or development agility, but they do not provide many of the features that Descartes does with DOM-based styling, better computation, and dynamic values. Is there enough in Descartes to tip the scale?

Want to hear people's thoughts.

JonHMChan avatar Feb 18 '16 13:02 JonHMChan

In my opinion, generating a stylesheet would undermine one of the main values of using Descartes, which is having dynamic styles directly accessible by Javascript after the page has been rendered.

That said, generating the CSS could be an optional configuration for those who want it. Maybe having a cached stylesheet and the JS styles overwrite them once they're loaded? Might affect overall performance, but still have faster initial loading.

dfosco avatar Feb 21 '16 14:02 dfosco

@dfosco I think you're spot on, especially with your second point. I think generating a stylesheet and having dynamic styles post-render are not mutually exclusive, precisely because Descartes uses inline styles and would overwrite anything declared by the stylesheet. The stylesheet in this scenario would be relegated to serving a caching and backup function: it would render at least the majority of the styles needed to get the (perceived) performance, then the actual dynamism of the library would kick in as it currently does.

JonHMChan avatar Feb 21 '16 18:02 JonHMChan

@JonHMChan are you saying that Descartes would split the styles? Generate the base css which is not dynamic and have js part have only the dynamic styles. That sounds like the fastest option.

vladanost avatar Feb 21 '16 23:02 vladanost

@krivinarius yes, that's exactly what I'm suggesting. I think having the base styles that are not dynamic (without using a function) would be generated and used for the initial load.

JonHMChan avatar Feb 22 '16 17:02 JonHMChan

@krivinarius you may be interested to see that https://github.com/JonHMChan/descartes/blob/master/src/descartes.js#L441 has been implemented to generate the base CSS, still no JS generated since I think I may refactor how event listeners are declared to make it a bit easier to bind and more performant overall.

JonHMChan avatar Jul 19 '16 01:07 JonHMChan