facebook / react-native

A framework for building native applications using React
https://reactnative.dev
MIT License
119.04k stars 24.32k forks source link

[View] Best practice for large number of views (100s)? #3203

Closed aroth closed 9 years ago

aroth commented 9 years ago

I've built a yearly calendar component that is made up of over 400 views (one per month, one per week, one per day, etc...). Unsurprisingly, performance suffers. Loading takes 3 to 5 seconds on the simulator and device.

screen shot 2015-10-02 at 6 39 39 pm

I don't need fine-grained interaction at this level, just a <Touchable.../> around each individual month that presents a detailed view.

Does React Native have a way to improve the performance of this use case? Or perhaps my component be designed without so many views.

I hoped shouldRasterizeIOS might help, but no such luck.

Thanks.

leafduo commented 9 years ago

I'm guessing you will get a performance problem even using UIKit, if it's the case, then react seems not be able to solve the problem because it's based on UIKit.

I'll try one CALayer for each day, using Core Graphic or one pre-rendered image for each month.

brentvatne commented 9 years ago

cc @sahrens @nicklockwood

ide commented 9 years ago

@leafduo might be right. With RN (very long-term idea -- not coming soon or even worked on necessarily...) we can apply the techniques from AsyncDisplayKit such as using CALayers instead of UIViews for certain components, and can also precomposite CALayers so that text and images don't necessarily take up their own CALayer even. A static layout could even have a dozen React components and produce just one CALayer!

Anyway as a more pragmatic solution, I would try a few things:

aroth commented 9 years ago

@ide @leafduo Thanks for the suggestions. Much faster using CALayers.

With a lot of <View ...>s With Views

With CALayer With CALayers

And optimized... Optimized

ide commented 9 years ago

@aroth nice! Did you bridge over a higher-level component that contains multiple CALayers (so you no longer have a React component per day)?

aroth commented 9 years ago

@ide I did.

<ARCalendarMonth key={ key } 
               month={ month.title }  
               weeks={ month.weeks }  
                data={ dayData } />

The bridged module creates a CALayer with CATextLayer sublayers for each day. I then flatten the whole thing into a bitmap. Works great. Thanks again.

ide commented 9 years ago

Thanks! Was curious about your approach and glad it's performing a lot zippier for you now.

sahrens commented 9 years ago

One of my favorite parts of react native is the ultimate escape hatch - you can just write it in native and plug it in if you want :)

It would be nice to create some affordances to optimize this kind of thing though. Computing your own layout instead of relying on text measurement could help, as could some compositing and/or CALayer directives on . ReactART might also work better for cases like this because it draws straight to the canvas.

Thanks! Was curious about your approach and glad it's performing a lot zippier for you now.

— Reply to this email directly or view it on GitHub https://github.com/facebook/react-native/issues/3203#issuecomment-147155591 .

GaudamThiyagarajan commented 6 years ago

What is the best practise for android on this issue? Rendering 100's of touchable is definitely slower.