Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Slow performance compared to “pure” react-native #4302

Open
vasafix opened this issue Nov 15, 2021 · 154 comments
Open

Slow performance compared to “pure” react-native #4302

vasafix opened this issue Nov 15, 2021 · 154 comments
Labels
v3 V3

Comments

@vasafix
Copy link

vasafix commented Nov 15, 2021

Describe the bug
I Wrote 2 lists, one using native-base components, second one using react-native components, and I am experiencing 2 to 3 times slower render on native-base side, my example consists of fairly simple list, so I wanted to ask if anyone else is experiencing similar performance issues, or for advice on what am I doing wrong or how to speed things up.

To Reproduce
In my example are 2 buttons, which will navigate you to respective list, with time it took to fully transition in ms.

Expected behaviour
Similar render times to react-native components.

CodeSandBox/Snack link
codesandbox template

Render times in ms

  DEV DEV DEV DEV PROD PROD PROD PROD
Native Base Android Android IOS IOS Android Android IOS IOS
  Emulator Samsung S21 Emulator Iphone 13 Pro Emulator Samsung S21 Emulator Iphone 13 Pro
1 1103 319 266 188 605 255 208 150
2 947 303 173 199 522 232 101 149
3 966 339 163 191 615 236 94 150
4 1069 306 157 191 496 211 101 150
5 919 307 154 192 543 209 90 150
Avg. 1000,8 314,8 182,6 192,2 556,2 228,6 118,8 149,8
                 
  DEV DEV DEV DEV PROD PROD PROD PROD
React Native Android Android IOS IOS Android Android IOS IOS
  Emulator Samsung S21 Emulator Iphone 13 Pro Emulator Samsung S21 Emulator Iphone 13 Pro
1 424 104 93 89 111 32 27 47
2 395 105 62 91 96 39 24 46
3 437 106 64 90 101 38 24 45
4 472 135 63 91 89 39 22 44
5 528 103 63 90 87 40 27 44
Avg. 451,2 110,6 69 90,2 96,8 37,6 24,8 45,2
@vasafix vasafix added the v3 V3 label Nov 15, 2021
@ezze
Copy link

ezze commented Dec 1, 2021

@vasafix Does it happen with any 3.x version?

I am experiencing an issue with 3.0.6 in Android: the more Native Base components are rendered the slower further rendering performance (i.e. when switching between visible app components). Each time I create and render a component including Native Base components I see more visible delays before my component starts to interact (run useEffect callback on mount). Seems like something is blocking event loop.

I don't see any performance issues if I switch to React Native components.

I thought that these issues might be related.

@md-rehman
Copy link
Contributor

@vasafix have you tried our latest release because we have done a lot to fix these kinds of performance issues.

So @vasafix and @ezze, I would highly recommend both of you share your feedback on the performance of our latest version (i.e., 3.3.2).

@ezze
Copy link

ezze commented Jan 17, 2022

@md-rehman My issue is resolved after upgrading to 3.2.2. Unfortunately, I can't upgrade to 3.3.x at the moment because it introduces new bugs like this.

@vasafix
Copy link
Author

vasafix commented Jan 19, 2022

@md-rehman Can’t compare, because after updating to 3.2.2. I am now getting error:

useTheme must be used within NativeBaseConfigProvider

New snack link (native-base-3.3.2)
This example is exactly same as the original one I posted, with difference of native-base version and its new dependencies @types/react and @types/react-native

@vasafix
Copy link
Author

vasafix commented Jan 26, 2022

@md-rehman Can’t compare, because after updating to 3.2.2. I am now getting error:

useTheme must be used within NativeBaseConfigProvider

New snack link (native-base-3.3.2) This example is exactly same as the original one I posted, with difference of native-base version and its new dependencies @types/react and @types/react-native

Seems that 3.2.4 fixed this error, I will make new render time table

@fatshotty
Copy link

Hi @vasafix
did you try with a new render time table?
I upgraded nativebase to latest version ( 3.3.7 ) but low-performance problem is still there

thanks in advance

@qlereboursBS
Copy link

My company and I also have performance issues
A simple test can be done like this:

const TestComponent = () => {
   const [data, setData] = useState(0);
   useEffect(() => {
       const interval = setInterval(() => setData(d => d+1), 100);
       return () => clearInterval(interval);
   }, [])

   return (
       <>
           <Text>{data}</Text>
           <Button onPress={() => console.log(data)}>Click me!</Button>
       </>
   )
}

It simply rerenders every 100ms. When importing Button and Text from NativeBase, there's a latence on the button (like a few seconds), but when importing from ReactNative, or other libs like MagnusUI, there's no (or a few ms) latence.
This is a stress test, but you will have the same issue with 1s rerender frequence.
It's an issue which should be high priority, because it prevents to use NativeBase as a component library.

I think a good first step would be to check which component has to be optimized, to understand if it's the whole library (because of the contexts?, or the way props are computed?) or only a few components

@pierroo
Copy link

pierroo commented Mar 16, 2022

Unfortunately I also have to step in and confirm that as of today nativebase just isn't viable in production for android devices.
I am currently undergoing the process of rewriting my whole app (which is live and distributed to millions of users...) using simple react native component; what a bummer.

If there is any plan on improving performance for android I would love to hear about it.

@Wei102193
Copy link

I posted a similar issue on This.
I believe the more React Native components you use the slower your app will be.
Native Base is great. But this is a big issue. Most people will get rid of Native Base from their code because of it. And it is too sad that they have to rewrite their project in pure react-native if their code heavily depends on it. So read this before you dive deeply into native base. Hope they can fix this issue soon.

@arunim2405
Copy link
Contributor

https://snack.expo.dev/H3aB8nOYG
The lag is still there and it is still significant.
I have discovered this issue right before pre-production testing and I have no idea how I am going to replace these many components.

@tankers746
Copy link

tankers746 commented Apr 11, 2022

After doing some profiling the issue seems to lie with with this function which is called on every render of every component

export const usePropsResolutionWithComponentTheme = (

Ideally this could be refactored to reduce the new object allocation.

@rayan1810
Copy link
Contributor

Hey folks, performance is on the top of our priority list right now, we wanted to stabilize a few things before jumping on this ship hence the delay, but be assured NativeBase will have the performance issues sorted in the upcoming weeks.

@seeden
Copy link

seeden commented Apr 13, 2022

Benchmarks: https://tamagui.dev/docs/intro/benchmarks

@thirteenthstep
Copy link

Those benchmarks are actually quite shocking. I can confirm performance problems when navigating to new screens, where users experience a significant delay while the new screen is being rendered.

@rayan1810
Copy link
Contributor

The tamagui benchmark results are quite old, If I remember correctly these results were out when NativeBase v3 was initially released. But since then it has already improved significantly but yeah much more work is needed and we are already on it ✊ .

@ababol
Copy link

ababol commented May 3, 2022

I can confirm we also have huge lag issue on Android using native-base.

Especially on list, we have to really be careful on changing a state/re-rendering list, we try not to in Android.
We had to disable some feature on our app because of that.

@pierroo
Copy link

pierroo commented May 3, 2022

I can confirm we also have huge lag issue on Android using native-base.

Especially on list, we have to really be careful on changing a state/re-rendering list, we try not to in Android. We had to disable some feature on our app because of that.

Make sure to use pure/memoized component like you mentioned, but not only:
when inside a list, I make sure the renderItem does not render native base component, I go back to pure react native Views and it does fix the list performance issue.

Of course this is just some temporary "hack" while waiting for native base to fix those performance issues...

@ababol
Copy link

ababol commented May 3, 2022

@pierroo Yes, thanks a lot for the recommendation, but in our case we cannot really afford that, one of the main component of our app EventCard is written using native-base in order for us to have it working on both the app and the web, that's actually one of the main reason why we choose native-base

Rewriting this component in pure react native would probably help a lot with the performance issue (thanks a lot for the suggestion), but it would also be like dropping native-base and its benefit/why we choose it :(

Screenshot 2022-05-03 at 14 55 10

@foyarash
Copy link

foyarash commented May 4, 2022

Hello

We had the same performance issues as described in the previous comments. The issue was mostly visible on Android, but also on iOS.

We did a workaround requiring some work, but allowing us to keep a majority of native base props, by using the useStyledSystemPropsResolver hook, which is not impacted by any performance issue. By doing that we saw an improvement of more than 50% for the first render time of our most impacted screens.

Here is an example implementation for the Box component:

const Box = forwardRef<View, React.PropsWithChildren<BoxProps>>(
  ({ children, _text, safeAreaBottom, safeAreaTop, ...props }: React.PropsWithChildren<BoxProps>, ref) => {
    const [style, otherProps] = useStyledSystemPropsResolver(props);
    const { top, bottom } = useSafeAreaInsets();
    const safeAreaStyle = useMemo<StyleProp<ViewStyle>>(() => {
      const baseStyle: StyleProp<ViewStyle> = {};
      if (safeAreaBottom) {
        baseStyle.paddingBottom = bottom;
      }

      if (safeAreaTop) {
        baseStyle.paddingTop = top;
      }

      return baseStyle;
    }, [safeAreaBottom, safeAreaTop, top, bottom]);

    return (
      <View {...otherProps} style={[style, safeAreaStyle]} ref={ref}>
        {wrapStringChild(children, _text)}
      </View>
    );
  }
);

Where View is imported from react-native.

For the rest of the component, the goal was to also mimic how native-base would interact with the theme, for example for the Pressable or the Button component.

Hope this will help.

@arryanggaputra
Copy link

@foyarash very impressive 🔥. Have you managed to fix the Button performance issue? Can we know your implementation?

@foyarash
Copy link

foyarash commented May 9, 2022

@foyarash very impressive 🔥. Have you managed to fix the Button performance issue? Can we know your implementation?

I made a gist with the few files i used https://gist.github.com/foyarash/fa260a37fae9b085b89af13f61f46713

This worked well in our case since we don't have to handle dark mode for our app, so keep in mind that it really depends of the features you're using with native base.

@antoinerousseau
Copy link

@rayan1810 any progress on this? Do you need any help?
If we can assist or support let us know :)

@iooi
Copy link

iooi commented May 18, 2022

+1. I feel the lag on iOS while using NB for a couple of weeks. Really need to re-think if i need to abandon it. I am a paid customer.

@frossi85
Copy link

While the issue described here is regarding Mobile, I am experiencing a similar issue using native base with NextJS. The biggest issue is observed on inputs that use text like Input and TextArea. Writing fast on the input does not provide instant feedback but takes a while between typing fast and seeing what was typed reflected in those inputs. Also, there are some slow animations. So I guess the issues are in the core and not the platform-specific implementation.

Does the team have a deadline? I am asking because started to implement something that needs to go to prod in 2 months but if the issue remains I will need to replace Nativebase.

@rayan1810
Copy link
Contributor

Hey folks, we are currently working on it and have already fixed components like Checkbox, we have found that the major performance issue is on Android. Currently, we are trying to resolve component theme props at boot time and inline props at runtime. I guess this will reduce the overhead on the JS Engine during runtime and give a perf boost to the App.

@rayan1810
Copy link
Contributor

Also for the perf issues on other Platforms apart from Android, It would be really helpful if you guys can share some code snippets and GIFs of the same.

@pierroo
Copy link

pierroo commented May 18, 2022

Hey folks, we are currently working on it and have already fixed components like Checkbox, we have found that the major performance issue is on Android. Currently, we are trying to resolve component theme props at boot time and inline props at runtime. I guess this will reduce the overhead on the JS Engine during runtime and give a perf boost to the App.

Thank you for your reply and information.
Having fixed Checkbox is great for sure, but considering the hundreds of other components that needs to be fixed as well, is there any way to follow up the progress or have some kind of roadmap to better align our expectations?

Somehow, there must be some issue in the core of native base and its way of writing components, that once found out and fixed should be easily replicated overall, no?

Not gonna spoil this thread, but another easy way to see how slow the overall components are, switching from day to night mode in the app takes around 2-3 seconds, where it happens almost instantly with any other provider.
Maybe this will be improved with your current work on boosting runtime?

@kapobajza
Copy link

The problem is that the issue wasn't handled at all. They just abandoned this project and moved to another one. That behavior is really irresponsible and because of that they won't have my support for their Gluestack project, even if it was the best UI lib out there. I mean who's guaranteeing you that they won't silently abandon that project either, like they did this one? We shouldn't support people like them, financially or in any other sense.

On another note: I managed to completely ditch native-base from my project and proceed using my own, custom implementation. Replacing native-base had to be as painless as possible, so I decided to have a similar API (for the utility props at least) as they have. For anyone who's interested in the implementation, I have created a test project and you can check it out here.

@iBotPeaches
Copy link

End of an era. Unsubscribing from this thread. We left for Tamagui. Took about ~30 billed hours for a migration off of NB to Tamagui.

I wish no ill will or toxic comments, but this did not play out in a positive light to us for how the situation was handled. So we felt it was best to move on.

@sanketsahu
Copy link
Collaborator

First of all, I accept and own this issue. This was my fault in its entirety. We tried our level best to solve it, and we have worked day in and day out to fix the perf issue with the existing APIs but we couldn't.

  • The API in v3 was built so that it had to depend on the JS runtime, and it couldn't be swapped out with a build-time equivalent. So, a rewrite of the library and the migration to the existing project was necessary. For eg, in the initial design of NativeBase v3, we didn't consider using the $ prefix, which makes it easy to write the build-time optimizers, which we built with gluestack-style (aka dank.style).
  • The library had styles baked into it which made it hard to decouple it, and the only good way to write your own theme was to extend the base one
  • Third, the component library and the styling engine was coupled together, which made it unmaintainable.

Why did we abandon this project for another one?
We actually didn't! gluestack-ui / gluestack-style was named NativeBase v4 initially, but considering the number of necessary changes, we renamed it to something else.

Why should you trust the library authors any more?
We are literally trying our best. But it's up to you. In full transparency, about 20 engineers and designers are working full-time on gluestack since December 2022. Most of the work has gone into gluestack-ui and gluestack-style. We are building more projects on top of gluestack-ui at GeekyAnts. In fact, if you check gluestack.io and all the websites, they are all built with gluestack-ui.

And tamagui is a great project, and Nate is extremely talented! @iBotPeaches You have made the right choice! Sorry for the ~30 hours of extra billed hours. It wasn't our intention to waste your time - we're working our socks off here. Beyond the 30 hours, I've had my share of sleepless nights over this. My heartfelt wishes for your projects, and I hope for nothing but success for you.

@kapobajza
Copy link

First of all, I accept and own this issue. This was my fault in its entirety. We tried our level best to solve it, and we have worked day in and day out to fix the perf issue with the existing APIs but we couldn't.

  • The API in v3 was built so that it had to depend on the JS runtime, and it couldn't be swapped out with a build-time equivalent. So, a rewrite of the library and the migration to the existing project was necessary. For eg, in the initial design of NativeBase v3, we didn't consider using the $ prefix, which makes it easy to write the build-time optimizers, which we built with gluestack-style (aka dank.style).
  • The library had styles baked into it which made it hard to decouple it, and the only good way to write your own theme was to extend the base one
  • Third, the component library and the styling engine was coupled together, which made it unmaintainable.

Why did we abandon this project for another one? We actually didn't! gluestack-ui / gluestack-style was named NativeBase v4 initially, but considering the number of necessary changes, we renamed it to something else.

Why should you trust the library authors any more? We are literally trying our best. But it's up to you. In full transparency, about 20 engineers and designers are working full-time on gluestack since December 2022. Most of the work has gone into gluestack-ui and gluestack-style. We are building more projects on top of gluestack-ui at GeekyAnts. In fact, if you check gluestack.io and all the websites, they are all built with gluestack-ui.

And tamagui is a great project, and Nate is extremely talented! @iBotPeaches You have made the right choice! Sorry for the ~30 hours of extra billed hours. It wasn't our intention to waste your time - we're working our socks off here. Beyond the 30 hours, I've had my share of sleepless nights over this. My heartfelt wishes for your projects, and I hope for nothing but success for you.

That is fine, your reasons are on point. The only thing that you could've done better is be more transparent about that. A little warning or note in the Readme of the NativeBase project (something like: we're migrating to gluestack/dank.style) should've been sufficient. Or better yet: a warning about the migration and a link to a more detailed explanation about why you decided to do that.

I am sorry about not trusting you and calling you irresponsible, because you're not irresponsible. It's just that I wasn't aware of what exactly is going on with this project.

@sanketsahu
Copy link
Collaborator

@kapobajza Thanks for understanding! We have taken note of your feedback. We will update the content wherever necessary and be transparent going forward.

@gvanderclay
Copy link

@sanketsahu I firstly want to recognize the incredible efforts and dedication it must take to maintain an open-source project at the scale of NativeBase. Your transparency in acknowledging the issues and outlining the robust work done to address them is greatly appreciated.

However, one area that our team is deliberating over now is a migration from native-base. Do you have any plans to create a "Migration from native-base to gluestack" guide? This could be an instrumental resource for aiding our engineers in transitioning away from native-base more efficiently. I understand that creating such a guide is no small task, and could be a significant ask given the newness of gluestack.

@sanketsahu
Copy link
Collaborator

@gvanderclay Thanks for your kind words! The migration guide is on our list. We have written the initial version on Notion. We will share it as soon as we have a draft.

@dimitrisoikonomou
Copy link

Thank goodness I read this before I started using it in my app I'm about to build. I think I'll go with pure RN or do you have a better UI library to suggest me?

@dondxniel
Copy link

@dimitrisoikonomou check out tamagui. It's super fast and sleek with sweet animation capabilities. Problem is it has a complex setup process and a seemingly incomplete documentation. I'm currently using it for my app and I have to do a lot of learning. It slows down the process in the beginning but it'll get faster the more you understand it. It's definitely worth checking out.

@sanketsahu
Copy link
Collaborator

Thank goodness I read this before I started using it in my app I'm about to build. I think I'll go with pure RN or do you have a better UI library to suggest me?

@dimitrisoikonomou You can also check ui.gluestack.io which is the successor of NativeBase with a focus on performance & DX!

@dondxniel
Copy link

@sanketsahu does it have the exact same features and setup as nativebase? Also, do you know the performance quality compared to tamagui?

@sanketsahu
Copy link
Collaborator

@dondxniel We have more features than NativeBase. The API has changed a bit to have build time optimizations. You can find out more here: https://nativebase.io/blogs/road-ahead-with-gluestack-ui

The perf is similar to tamagui as we are doing the same thing. We will release the benchmark comparison in the coming days. The entire website is built using gluestack-ui.

@dondxniel
Copy link

That's nice to know. I'll check it out right away; thanks!

@jy1989
Copy link

jy1989 commented Jan 30, 2024

@dondxniel We have more features than NativeBase. The API has changed a bit to have build time optimizations. You can find out more here: https://nativebase.io/blogs/road-ahead-with-gluestack-ui

The perf is similar to tamagui as we are doing the same thing. We will release the benchmark comparison in the coming days. The entire website is built using gluestack-ui.

my android app facing the performance problem too. and I take long time to find out this issue from nativebase.
and the solution is to rewrite the app?

@uen
Copy link

uen commented Jan 30, 2024

@jy1989 yep. it's very frustrating. there should have been a giant readme banner back in 2021 telling people that this library has serious performance issues. i replaced everything with my own primitive components that support utility props and have never looked back

@jy1989
Copy link

jy1989 commented Jan 31, 2024

@uen I found that this native base version "3.5.0-rc.7" has better performance. So I am currently using this version for the time being

@akash3gtm
Copy link
Collaborator

Hi Everyone,

We have made @gluestack-ui/themed-native-base that will work as a drop-in replacement for native-base.

It shares the same API, styling, functionality as native-base. But internally it uses gluestack-ui, so you will notice a massive performance boost in your application (web and native).
Basically, you get the performance of gluestack-ui without changing your code base, you just need to change the imports (you can alias the imports).

The library is currently in beta (apart from minor styling and typing issues, it is stable), we would love for you to try it and report as many bugs/issues you can find, so we can release a more stable version .

@kylegwalsh
Copy link

@akash3gtm Are there plans to have it support the old native-base way of extending the theme types?

Or any other compatible way to use the same theme to declare theme types?

// Get the type of the CustomTheme
export type CustomThemeType = typeof theme;

// Extend the internal NativeBase Theme
declare module 'native-base' {
  interface ICustomTheme extends CustomThemeType {}
}

@akash3gtm
Copy link
Collaborator

Hi @kylegwalsh ,
Yes we have plans to give 100% ts-support the same way we gave in native-base so all the typings come correct.
As soon as we are done with minor fixes and issues, we will release v1.0.0 soon with everything.

@kylegwalsh
Copy link

Thanks for the reply @akash3gtm! I attempted to replace all instances of native-base with the new gluestack package as an experiment, but ran into some issues getting it to render in my expo app.

There could be any number of confounding issues since native base was so engraved into my code (and I handled custom theming for different users), so I'll keep a lookout for v1.0.0 and try again once it's released!

@akash3gtm
Copy link
Collaborator

Thanks for the reply @akash3gtm! I attempted to replace all instances of native-base with the new gluestack package as an experiment, but ran into some issues getting it to render in my expo app.

There could be any number of confounding issues since native base was so engraved into my code (and I handled custom theming for different users), so I'll keep a lookout for v1.0.0 and try again once it's released!

Hey @kylegwalsh ,
As of right now it should not break, but we have not tested it extensively on any large complex projects.
The projects we did test it on, were our native-base docs website that was made using native-base, some expo apps and react apps and some other 4-5 pages nextJS app.
If you could open an issue in the git repo @gluestack-ui/themed-native-base, and provide either an expo snack or code-sandbox, we would be able to see what is the error causing this.

@kylegwalsh
Copy link

Hi @akash3gtm, got it. I will give it a shot after finishing a few other priorities on my plate. It may be a bit difficult to boil it down into a snack because of the complexity of the application. It will probably take me several days of digging.

I even tried commenting out the entire app tree to just get a successful render and still saw the error (it seems that expo-router is erring when trying to require screens from other areas of the app that leverage gluestack components:

Uncaught Error: Requiring module "app\(interstitials)\_layout.tsx", which threw an exception: TypeError: Cannot read properties of undefined (reading 'colors')

@akash3gtm
Copy link
Collaborator

Hi @akash3gtm, got it. I will give it a shot after finishing a few other priorities on my plate. It may be a bit difficult to boil it down into a snack because of the complexity of the application. It will probably take me several days of digging.

I even tried commenting out the entire app tree to just get a successful render and still saw the error (it seems that expo-router is erring when trying to require screens from other areas of the app that leverage gluestack components:

Uncaught Error: Requiring module "app\(interstitials)\_layout.tsx", which threw an exception: TypeError: Cannot read properties of undefined (reading 'colors')

Hi @kylegwalsh, would be more than happy to help you resolve the issue.
Whenever you have enough time, Please raise an issue in that repo, and we will help you get it all setup.

@Drzaln
Copy link

Drzaln commented Apr 4, 2024

Hi @foyarash can you show me how to make Stack component with space props? A bit lost in there

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
v3 V3
Projects
None yet
Development

No branches or pull requests