Mounting many components – performance question.
See original GitHub issueI’ve been using styled components for the last few months as the basis for a new app. It’s been a great experience. However, as the app has grown, I’ve been noticing that the styled components are taking slightly longer to render than vanilla JSX, usually freezing the browser in the process 💅.
I’ve been trying to debug to find the bottlenecks, and styled components is appearing near the top of most Chrome profiles. When rendering lists of ~20 fairly large styled components, the browser freezes until they can mount. Thinking it was a performance bug in my code, I removed the presence of styled components to narrow down the bug, but the problem disappeared. The list loaded React-Fast™.
Most of the styling is handled with base components. e.g. <Flex />
, <Box />
, <Text />
etc. These are styled-components that are setup to accepts props for most of the commonly used CSS properties. e.g. position
, display
, border
, background-color
, color
, flex
, etc. There are about 50 props like this that are accepted on each base component.
I’ve created a replication on the issue in WebpackBin. I ported over my Base component factory to expose that code for any potential bottlenecks. The Bin is comparing two lists of 5K (scaled to demonstrate the performance) text rows, one built with styled components, and the other with vanilla jsx. When switching between lists or re rendering a list, try scrolling or interacting with the browser to see the browser lag.
What is going on with this performance lag? My theory is that when 💅 is inserting the styles, the browser forces a re-layout/paint. This is acceptable in minor cases, but seems to scale into a larger issue when there are many styled components mounted/unmounted/rendered at once. Would love some help on this one. Thanks.
Issue Analytics
- State:
- Created 6 years ago
- Comments:7 (4 by maintainers)
Top GitHub Comments
@philpl Good stuff, thanks.
I agree that a list of 5000 rows is unlikely. Even so, if styled components are heavily used, it’s very likely ~1000 components could be mounted/unmounted at once when changing routes or just displaying a lot of data. I’m just concerned for the overall performance of an app as the number of styled-components on screen grows.
React does have some problems mounting/unmounted large component trees, so I’ve been using a HOC to help defer the rendering to the next animation frame. It’s helped a lot with perceived performance, and FWIW, has helped loading complex styled components as well. It’s a bandaid until the source of the bottleneck can be found.
Cheers 💅
@derek-duncan I’d suggest to test real-world performance, in a production like environment instead, and try to keep your general-purpose components low and optimised.
General purpose components don’t add a lot of value IMHO and can introduce hard to fix performance problems in a non-trivial way