streamich / nano-css

Distilled CSS-in-JS for gourmet developers
The Unlicense
426 stars 24 forks source link

Painfully slow in development #191

Closed steadicat closed 1 year ago

steadicat commented 6 years ago

Currently nano.rule and nano.put use individual calls to appendChild to add rules to a <style> tag while in development. As the stylesheet grows, some appendChild calls can take up to 30ms (see screenshot), which for large updates can add up to several seconds (3.6s in my example below).

This could be made a lot faster by batching updates together and setting the <style> tag content using innerText.

Simple batching using requestAnimationFrame is not super efficient – due to the overhead of lots of requestAnimationFrame/cancelAnimationFrame calls – but it cuts the time down by ~30x, which is acceptable. Would making the updates to the stylesheet asynchronous have any major downsides?

Alternatively, an explicit batching/transaction API could be introduced, but that seems overkill for something that’s only an issue in development.

Any other ideas?

image
streamich commented 6 years ago

One idea is not to use .appendChild in DEV, but to insert only using .inertRule just like in PROD.

streamich commented 6 years ago

This could be made a lot faster by batching updates together and setting the <style> tag content using innerText.

You mean creating a <style> tag for each batch? Or just .innerText += rawCss?

I'm not sure .innerText is faster than .appendChild, also, if I remember correctly, there were some correctness issues when inserting using .innerText.

But we can probably batch in DEV. The only purpose of .appendChild in DEV is to insert styles such that Chrome shows them in Devtools, styles are inserted using .insertRule anyways. So, I guess, batching them and postponing insertion of these "pretty-printed" styles should have no effect.

steadicat commented 6 years ago

You mean creating a