You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Render at least two precedence levels, for example 'a' and 'b' so that react can insert our stylesheets into the head rather than inline.
Render lots of style elements into 'a' (your first precedence level, the important part is that react inserts our stylesheets into the head) and observe performance. Compare this to rendering without any precedence at all.
Seems like each style tag is handled independently with very little optimization - which is probably fine if you only load one or two stylesheets but doesn't work well for larger amounts of styling. In the attached example, you should also notice that every time we toggle our styles with precedence our performance gets worse and worse.
Here's a real example of render performance on my M1 mac pro. This isn't from the attached example, but is the same issue just at a larger scale:
Zooming in, most of the performance hit seems to come from query selectors and from actually inserting each stylesheet.
The expected behavior
Stylesheets should ideally render in similar time regardless of precedence.
We've (at @mui) have also come to a similar conclusion that the current implementation of of style hoisting (mainly on the client side) is rather slow pertaining to the dom querying that occurs to hoist each style tag.
I was able to improve the perf on the client side with this patch by a factor of 17 in a test of rendering 10000 different components with a style tag having both href and precedence.
React v19 took 3659.1043ms to append the dom items vs 215.73ms with the patch. Note that the patch is fully client side and does not consider hydration or RSC. So I am sure this isn't a proper solution, just something in the right direction.
@eps1lon the attached flamegraph is from a production next.js build with mangling disabled.
Some timings:
On A Production Site
The above patch does seem to help. It seems to have some issues with SSR though.
stable react: 4.5s
patched react: 97.88ms
When I remove precedence the site gets much slower, likely due to the massively increased DOM size. Still,
stable react, no precedence: 698.64 ms
patched react, no precedence: 904.13 ms
Within Codesandbox Reproduction
In the attached codesandbox example with the letters, I've observed this with mid-tier mobile CPU throttling:
No precedence: 1.01s
With precedence, first render: 5.65s
Because we're adding more and more to the DOM our performance will decrease over time. For example, when rerunning the letters example with precedence, a second render took 15.31s and our third took 26.88s
React version: 19.0.0, 19.1.0
Steps To Reproduce
Link to code example:
Here's a codesandbox demonstrating the basic issue:
https://codesandbox.io/p/sandbox/react-style-perf-t7w9qr
Or a github repository, if you prefer:
https://github.com/RJWadley/react-style-perf
The current behavior
Seems like each style tag is handled independently with very little optimization - which is probably fine if you only load one or two stylesheets but doesn't work well for larger amounts of styling. In the attached example, you should also notice that every time we toggle our styles with precedence our performance gets worse and worse.
Here's a real example of render performance on my M1 mac pro. This isn't from the attached example, but is the same issue just at a larger scale:
Zooming in, most of the performance hit seems to come from query selectors and from actually inserting each stylesheet.

The expected behavior
Stylesheets should ideally render in similar time regardless of precedence.
Related: #30739
The text was updated successfully, but these errors were encountered: