felipecespedes / react-native-bigheads

Big Heads avatars for React Native
MIT License
93 stars 13 forks source link

Huge Performance Issues #7

Open mrousavy opened 4 years ago

mrousavy commented 4 years ago

Hi! While I really like the drawing style of the characters and want to use them to identificate users instead of profile pictures, I cannot do so. Unfortunately the render-time of a single bighead is so high, that I simply cannot use it in production (yet). I also created a screen where the user can customize his BigHead, which renders even slower.

I'm talking about noticeable delay in initial rendering (mounting) (see this demo), and generally really slow renders on re-rendering when a prop changes (see this demo). Those are definitely UI thread lags, so the vectors must be composed using expensive techniques, such as clipping, which could be optimized.

I am trying to debug why this renders so slow, as normally vector rendering should be really fast. Now to my actual question(s):

  1. What could possibly be the cause of those incredibly slow renders?
  2. How can I debug/perf-measure this?
  3. @felipecespedes Could you maybe take a look at this and help me figure this out so I can use this in production?

All kinds of help appreciated 👍

felipecespedes commented 4 years ago

After initial research this seems a problem related to the <Mask> component from react-native-svg, however more investigation is needed. As a workaround, you could try using the prop showBackground={false} hopefully, it will increase the performance of your app.

mrousavy commented 4 years ago

@felipecespedes I've tested with showBackground={false} but didn't really notice a difference. I guess it's a few ms faster on re-renders?

Here's a new demo: https://i.imgur.com/OBzBCNi.mp4

Keep in mind that there is still a slight delay between click (grey circle appearing) and re-render completion (actual purple circle appearing). The delay is most noticeable when changing clothing, since I render the clothing multiple times to give the user the possibility to preview colors, see this demo: https://i.imgur.com/yE3K8Nb.mp4

Also, I've only tested this on an iPhone 11, iPhone 8 and my simulator on my i9 MacBook Pro, so the performance issues must be huge on low-end android devices or even older iPhones.

mrousavy commented 4 years ago

@felipecespedes After a bit of investigating, I don't think it's actually expensive to draw. I've measured a few parts of the JS code, and it looks like building the JSX tree is incredibly slow, especially in my use case where I'm drawing each part as an individual component (to make a selectable list), and then the full Avatar again.

Not exactly sure if it's the React.Context API's fault (used by useTheme), the table lookups, or something else that's hogging up the render function, but this definitely needs some refactoring...

Also, not entirely sure the JSX tree building is slow, it might also be the passing over the bridge. But it definitely isn't hogging up the UI thread, since you can see the navigation animation working smoothly.

Stophface commented 2 years ago

@mrousavy Can you share how you imported the individual parts for drawing? I mean, how did you only draw the shirt, the mask, the glasses, ...? I'd be interested in that.

pierroo commented 1 year ago

Is there any news on the above? (hopefully I am not too late to the party) @mrousavy did you find out the performance issue cause? and ideally, a fix to that?

Stophface commented 1 year ago

@pierroo I am using this lib in production and I do not recognize any performance issues tbh