What is the best way to implement a scrollable list of several thousands items in React Native? - react-native

To be short, my requirements are:
The list needs to contain about 5 thousand average product cards in two columns. The products are splitted into sections.
It must be performant, really performant
I need it to work well with onViewableItemsChanged method
I need to be able to scroll it to the desired position as quick as possible
It must be able to be Animated with the native driver (e.g. to animate header according to the scroll position)
I've tried to use SectionList for my purpose, but it did not achieve the desired performance despite many tweaks of the virtualization parameters. The problem was that the responsiveness of the app gradually got worse as I scroll down. It was because of the amount of items above the viewport. Yes, SectionList do detach the items outside the viewport, but it replaces it with the getItemLayout function, which floods the thread and hangs the app for about 3-4 seconds before it starts responding.
Another way I tried was to use react-native-big-list. This thing works really well with lists like mine, like really fast, exactly how I need it to work. But sadly it is not perfect and has some unsolved issues:
the onScroll method here does not work with Animated.event with the useNativeDriver prop set to true
the onViewableItemsChanged stops working as soon as I reach the second section of the lists
the scrollToLocation method does not support the viewOffset prop.
All the issues above are known but still not resolved, and I am not as good to somehow patch them (in fact I tried)
I do hope that someone have the same problem solved.
Sorry for my mediocre English, but hopefully I expressed my thoughts good enough to be understandable

Related

Flatlist not smooth with lot of image per item

I use a flatList to make my activity feed.
However, I have a problem with the fluidity of my list
Each item can render up to 80 static images of 25kb, each in an absolute view, I still have to play with the performance when I mount my components but when I scroll, if I have my 80 images per item, my list is absolutely not fluid!
However, when I check my rendering number, I have very few because I use PureComponent for my items.
I check the RAM, and everything looks good!
My UI and JS Threads are constantly at 60!
Could this be due to the number of views I see in "Perf Monitor" that goes up to more than 3000? If it's that, how do I fix it?
Hoping to have a solution,
Thank you
Viktor
I've been facing the same issue , but after reading docs ive implemented the below :
You can use the community packages (such as react-native-fast-image
from #DylanVann) for more performant images. Every image in your list
is a new Image() instance. The faster it reaches the loaded hook, the
faster your Javascript thread will be free again.
You should always use react-native-fast-image for more images.
Hope it helps. Feel free for doubts
I had issue in my android version. I set resizeMethod="resize". This gave me massive performance boost.
I was loading lot of large images in section list and FlatList. Using resizeMethod as resize resolved my issue, and scroll is buttery smooth after this.

How to render a big dynamic list view with react-native

I have a CMS page which might includes goods or images floors. The images might not have a certain ratio or size.
And the product component should support adding to cart.
I'm using FlatList to render these data. But it seems like it's not a good choice cause the rendering processes quite slow and it looks like main thread will be blocked during the first rendering. And when scrolling quickly, there will be some empty blocks.
After reading the document of recyclerlistview from Flipkart, it seems like it's not a good choice for encouraging a certain layout size of each row, while images of my floors does not have.
Is there any suggestion to render such a CMS page with RN?
FlatList itself is a Slow component. It has huge gain from a memory perspective but performs slow.
Try to use https://github.com/bolan9999/react-native-largelist package for large lists, This seems to perform better for me.
#Shahen Hovhannisyan's answer is good suggestion.
But considering react-native-largelist has a lower rate and star. I did not import it in our project.
My solution is keeping use of react-native's FlatList. And wrapping items with React.memo or using PureComponent instead of Component to avoid wasted renderings. I also gave a certain layout for images. In my experience, this will increase FlatList's rendering experience. Replacing Image with react-native-fast-image is also an effective improvement. This will cause a lower memory usage and a better cache. BTW, for react-native 0.59, use react-native-fast-image 6.1.1 for the latest version only support RN 0.60+.

Can you force a full render of a list in Office Fabric?

I'm working with a List in Office Fabric, specifically a DetailsList. Within my list, I have a number of images that are pretty expensive to render, as well as a pretty big list of rows. Unfortunately, this means when I scroll down, there's a huge lag as the page is re-rendering new images (also frustratingly because it destroys the previous images, if I scroll back up it's similarly laggy).
Is there a way to force a render of the entire list so that it doesn't have to re-render when you scroll up or down? I don't mind having a long initial loading time as long as the actual scrolling portion doesn't have a high latency/isn't slow or jerky.
You can disable virtualization by returning false in the DetailsList's onShouldVirtualize callback.
The team is actively working on improving List / DetailsList virtualization in the coming months.
Relevant documentation pages describing the above prop:
https://developer.microsoft.com/en-us/fabric#/components/detailslist
https://github.com/OfficeDev/office-ui-fabric-react/blob/738e270892f99957aecf567e4b107f8e4cf86176/packages/office-ui-fabric-react/src/components/DetailsList/DetailsList.types.ts#L253

activeItemChange: How to speed up its performance?

In an attempt to optimize my app's performance, I've tried to cut down the number of elements in its main carousel as much as possible. I'm down to 3 first-order items (the one being viewed, along with N-1 and N+1).
I'd also like to cut out most of the contents of the N-1 and N+1 carousel items and programmatically add the contents for the item that is currently being viewed (so that the carousel items would look like this: http://i.imgur.com/gm7cL7E.png).
activeItemChange is the obvious choice here for the event listener. Problem is, it apparently is relatively slow, especially on low-end Android phones. It can take as long as 4 seconds to fire.
I've tried the carousel's onDrag property as a different way to fire the content creation, but asking the phone to do two operations (animate the carousel moving & create the new content items) makes the carousel movement animation choppy.
Is there any way to modify activeItemChange or the carousel to improve the listener's firing speed? Or any other listener I could be looking at that would perform better? I've done quite a lot of work optimizing overall performance on the app (shrinking the DOM, event delegation, etc) and the rest of the app runs quite well, so I'm not sure that doing general performance work will free up sufficient CPU to get activeItemChange to the level that I'd like.
Edit: I've done even more performance improvements in an attempt to free up enough CPU, to no avail. Any additional tips would be greatly appreciated.
Edit 2: It's been suggested to use order: 'before' for the event, as in:
listeners : {
order : 'before',
activeitemchange : someFunction
}
That does fire much more quickly. However, since activeItemChange has necessarily not been fired yet, I can't determine which item should get the carousel contents added. If I could determine which direction the carousel is going, that would be sufficient, but I can't seem to get that either.
Additionally, since Sencha seems to automatically paint N+1 and N-1 and erases N+2 and N-2, I was thinking I could use that as a more rapid determinant of where the item is in the carousel; unfortunately, based on the performance issues brought up in the Sencha documentation, it seems like it would end up with worse performance rather than better in the end.
Good question. Just a suggestion may or may not work. Instead of concentrating on the activeItemChange of the carousel maybe you could try the painted event of the container into which you want to put your items, or initialize event if the data is not going to change, initialize is faster than painted but only fires once so if your content is going to change use painted, otherwise try it out with initialize it may be the better way to do it.

Sencha Touch - Scroll Delay on First Touch

I have been searching around and it looks like this question has been asked quite a few times in various places with no answers or responses. That means that I can't be the only one experiencing this.
There is always a delay in the scrolling when you try to scroll a list or panel for the first time. After the first time you scroll a list or panel, there is no longer any delay. Is there a way I can simulate this "first touch" in an effort to remove the delay when attempting to scroll a list or panel for the first time?
I've been looking through the ScrollView and Scroller code and have not been able to find a point where anything heavy or expensive is happening on a first touch.
Any help or direction on how to remedy this would be greatly appreciated.
Thanks!
You can open the Chrome/Safari developer tools and start profiling("Profiles" tab) to see if there is any JavaScript code that is performing badly and causing the hang.
If it's not code that hangs, it might be a web browser issue (e.g. image cache allocation), for example due to the first time that things dynamically change in your web app.
It's also important to try and compare platforms and see if they have the same issue.
It's also often helpful if you specify the Sencha version (I assume 1.x?) and the platform(s) you've had the issue with. iOS/Android/PC can often react quite differently.