theKashey / used-styles

📝All the critical styles you've used to render a page.
MIT License
137 stars 9 forks source link

createCriticalStyleStream: problem with inserting styles into existing style tag #53

Closed hnrchrdl closed 9 months ago

hnrchrdl commented 9 months ago

There is an issue with interleaving styles when using style tags in react.

Suppose we have this react code:

// inside some react component
<div>
    <style>{`
        .myEl { color: red; }
    `}</style>
    <div className="some-class">
        some content
    </div>
</div>

Depending on the size of the style contents (and mostly when there is a lot of content in it), interleaving of critical css (using createCriticalStyleStream) outputs this:

<!-- server renders this -->
<style type="text/css" data-used-styles="some-file.css">
    .some-class { whatever: whatever; }
</style>
.myEl { color: red; } <!-- not wrapped in a style tag anymore! -->

Which leaves the custom css that was declared in the component without a style tag, meaning it will show up on the page as plain text (until the styles are moved / removed for hydration).

Hopefully, this can be fixed. I tried debugging the source, but I am lacking some knowledge around streams and transforms, so I was unable to come up with a proper solution to fix it.

theKashey commented 9 months ago

This can be a little tricky. In short one need to find an end of potentially opened style block and inject extracted styles only after it. Basically make this single line smarter - https://github.com/theKashey/used-styles/blob/master/src/reporters/critical.ts#L62