hydration is slower than React when there are a lot of contexts
See original GitHub issueIssue
When using a css-in-js library like emotion
of framework like theme-ui
(which uses emotion
) and with enough components, preact hydration takes longer than react. This increases the first input delay metric for the site when there are a lot of styled components.
My theory is due to the amount of contexts in the app as emotion
wraps each styled component in a context so that it has access to the theme. (When removing the contexts hydration times are comparable)
Reproduction
https://github.com/kenny-f/preact-hydration-repro
npm run build
npm run start:prod
Go to localhost:3000
To run the app in `react
Steps to reproduce
Run the performance profiler in chrome devtools (Start profiling and reload page
)
Here are some results:
Preact:
you can see from the gif below that the process is extremely deep:
React:
I’m not sure if this a known issue as I couldn’t find any information on it. Just our own observations when profiling our app that does not have much functionality right now.
Happy to provide more information if required.
Issue Analytics
- State:
- Created 3 years ago
- Reactions:4
- Comments:10 (8 by maintainers)
Top GitHub Comments
@developit i should have thought about this sooner, but the material ui repo has a benchmark setup for ssr, which could be useful to test this. I added to their setup to test several implementations of ‘styled’ libraries, and i was supprised to see styled-jss (the standalone version using jss v9) was by far the fastest. 2x faster than emotion and 5x faster than muis version. Emotion was ~50k op/s whereas styled-jss was close to 100k. Most others, including mui, were around 20k. I think this is likely due to using theme context, whereas styled jss only optionally uses the brcast based wrapper and doesnt wrap every component
@developit thanks for the response. Based on your reply I’ve done some more experiments.
First is dropping
theme-ui
and only useemotion
directly: https://github.com/kenny-f/preact-hydration-repro/tree/emotion-onlypreact:
react:
as you can see the timings for both have dropped significantly.
The second is dropping both
theme-ui
andemotion
and manually creating a ThemeContext and wrapping eachdiv
in aConsumer
https://github.com/kenny-f/preact-hydration-repro/tree/manual-contextpreact:
react:
The timings drop even further here. This does seem to suggest that your theory is correct in that theme-ui and emotion maybe the culprits