styled-components
styled-components copied to clipboard
Document React Native Performance Overhead
Steps to reproduce
- Create a list of items, one with items rendered normally, one with items rendered with styled-components
- Profile the list with the flamegraph
Expected Behavior
Both render in the same time
Actual Behavior
styled-components is about 25% slower
Suggestion
Performance overhead is documented or explained somewhere that is obvious.
There is an impression that the styling happens for free or 'magically', when it really adds a notable runtime overhead. This is most obvious in long lists of items.
Many people use this package in React Native and I've worked on a few apps that have faced performance issues related to it. React Native is particularly sensitive when it comes to performance, so I think this should be explained somewhere upfront in a 'caveats' section.
Totally fair, would you be up for writing it? I don't use React Native at all and am basically just keeping the lights on for the integration at this point since no other maintainers are focused on it.
@probablyup Thanks for the response, absolutely I would. Any guidance on where this should live in the docs? FAQ perhaps?
@tj-mc can you please run the same test against v6 now that it's released and let us know the outcome? Much appreciated, thanks!
@tj-mc wondering if you ever got round to testing the latest version? Thank you for making me aware of this issue!
Hi @efstathiosntonas and @Bowlerr 😄
I have created this reproducer to test and observe the performance differences. Included are some results from testing on my machine. When rendering 1000 empty views, I found a slowdown of 41% on v5, and 34% on v6.
That is a measurable improvement so we will upgrade our app, thank you for your work. I hope this reproducer can aid in further improving the performance.
Thanks @tj-mc, here are my findings on a M1 Ultra on iPhone 14 Pro Max simulator @ iOS 16.4, using expo@49 and [email protected]
| | 1 | 2 | 3 | 4 | Avg | % Slowdown |
|-----------|-----|-----|-----|-----|-----|------------|
| Native | 134 | 140 | 136 | 135 | 136 | 0 |
| Styled v5 | 235 | 226 | 225 | 232 | 229 | 68.38% |
| Styled v6 | 226 | 229 | 234 | 224 | 228 | 67.65% |
Just to make sure we're doing the same thing:
- Open React Dev Tools
- Click Profile red dot
- Tap the Switch to Native
- Wait a few secs
- Tap the Switch to Styled
- Stop the profiler
- Get the 224ms from the
App (0.3ms of 224ms)
from both commits ->StyledComponentsView
andNativeStyled
- Reload app and profiler, repeat steps 1-8 4 times
- Install
[email protected]
- Repeat 1-8 4 times
step 7 values:
The % Slowdown is the percentage difference between the Avg values.
package.json:
{
"name": "styledcomponents",
"version": "1.0.0",
"main": "node_modules/expo/AppEntry.js",
"scripts": {
"start": "expo start",
"android": "expo start --android",
"ios": "expo start --ios",
"web": "expo start --web"
},
"dependencies": {
"expo": "~49.0.2",
"expo-status-bar": "~1.6.0",
"react": "18.2.0",
"react-native": "0.72.1",
"styled-components": "^6.0.3"
},
"devDependencies": {
"@babel/core": "^7.20.0"
},
"private": true
}
That's correct @efstathiosntonas. I have tried with the exact expo versions you provided and it gave similar results. The actual numbers vary greatly depending on my machines resources but a general slowdown of at least 40-60% is measurable.
@tj-mc I've created a repo with all major style libraries, just fyi: https://github.com/efstathiosntonas/react-native-style-libraries-benchmark
Nice! @efstathiosntonas I did notice tamagui scored very poorly. It uses a compiler to optimise styles so maybe it performs better in release mode? 😃 Although, then how can we profile it 🤔 https://tamagui.dev/docs/intro/why-a-compiler#how-tamagui-helps
@tj-mc I've noticed that too, I've opened a discussion about it: https://github.com/tamagui/tamagui/discussions/1471
any updates on any improvements or suggestions on what to migrate to?
Update to the newest version of Styled if you can. I would recommended removing as much Styled as possible and replacing it with plain RN views and StyleSheet.create. It will always be slower since it has to work all this out at runtime.
Start with components being used in any sort of list as this is where the perf impact is most noticeable.
Hi all, I figured if you are watching this issue, you are trying to work out how to remove styled-components and improve app perf.
In our app, we opted to remove styled-components, since we have a very complex perf-sensitive UI, and we are not gaining much from using styled.
To assist those moving away from styled-components, I created https://github.com/tj-mc/eslint-plugin-no-styled-components
This simple rule prevents importing and/or using styled-components, which gives us better guardrails and allows us to slowly remove deprecate styled.
If this rule needs modifying for your workflow, please let me know.