1

So i have that casual problem of rendering large lists with ngFor, but my application being extremely laggy and taking too long to finish rendering.

My actual case:

I have multiple lists of mat-cards, which all have dynamically different and unpredictable sizes. Just to give you an idea, one list contains around 100 to 300 cards, all with buttons, icons and texts.

So virtual scroll from material cdk is not working for me because of the dynamic sizes. It should be possible to always switch between these lists, which leads to re-rendering them all the time.

I am already caching the http request for the needed data, so my problem is really only the browser rendering, not retrieving of data.

I also tried dynamic rendering with ng-template strategy, but that also not improved that much. And since i can always switch between the lists, it leads to race conditions while switching them.

RxAngular also did not help for my specific case.

After researching a lot in the web, i am now desperately looking for my final hope. Is there maybe a way to cache the actual rendered html, so that i can just reuse them while switching between the lists? Or any other advice and suggestion would be highly appreciated.

Thanks in advance!

Edit: More infos about use case: It is about a poetic book with multiple chapters. Each chapter has multiple verses and all of them can be commented on, favorised, copied and shared etc. And my client wants the whole chapter to be rendered in one huge list and whenever the chapter is switched it should be re-rendered at the same place. So i hope this information helps about understanding the issue

  • you should open the performance profiler in the browser and look for bottlenecks. 300 cards is a bit but should be doable without too much lag. There are a few things you can do that would probably help. Using changeDetection.onPush to avoid unneassary rerenders. Do not render things off screen would help a lot, granted that the dynamic height is an issue for virtual scroll from CDK. If you have a deeply neested dom tree, try change the desging to flatten it a bit. Could you share an example of a page, so we can see if there is a pit fall in template too? – Henrik Bøgelund Lavstsen Apr 20 '23 at 01:06
  • virtual scroll is harder related to "intersection observer". Some time ago (when angular/cdk have not "infinite scroll") Netanel Basal create one in this [link](https://netbasal.com/build-an-infinite-scroll-component-in-angular-a9c16907a94d) – Eliseo Apr 20 '23 at 07:03
  • @Eliseo this link helped me a lot, i think i fixed my problem now with this solution. Thanks a lot! – Kuhfleisched Apr 22 '23 at 15:25

2 Answers2

1

If you want to display 300 mat-cards with content inside all on one page, its just natural and normal that you experience performance issues.

There is no way (usually) why rendering 300 such items on one page at a time is necessary, or can you tell us more about your use case?

Some other options:

  1. Use the trackBy feature of the *ngFor Directive
  2. Implement Pagination

Why isn't virtual scrolling not working for your case? If you have the data from the api call you know the size before rendering. Also, implement cdk virtual scroll for every list, not one virtual scroll where you swap the list itself.

Hope it was helpful!

Don
  • 366
  • 1
  • 10
  • Thanks for your quick comment. Yes i know that it is natural, but i still hope for some way of optimizing it. Why cdk virtual scrolling is not working, is that the height in px are dynamic and not predictable, because they all contain different length of texts. But cdk wants to have fix item size. TrackBy also does not help, because when i switch the lists, the index of the items are also changed. Pagination is unfortunately not accepted, otherwise that would also be my choice. Reason for that is, that searching and filtering has to be implemented as well, pagination creates other UX issues. – Kuhfleisched Apr 19 '23 at 21:28
  • I edited the post with more informations about the use case, if it helps you to understand it better – Kuhfleisched Apr 19 '23 at 21:59
  • What if you try to implement a mechanic to just load the next items whenever the user scrolled to the bottom? Like https://stackoverflow.com/questions/38251205/check-if-user-has-scrolled-to-the-bottom-in-angular-2 and then you add the next batch to the list – Don Apr 19 '23 at 22:57
0

300 cards must not be a problem, you can render even 10,000 cards, perhaps you are doing some recursively or may a loop o may can be something external issue.

So, my suggestion is make a pagination, dont save the 300 cards in memory, you must speak with your team lead and back end team that provide you a pagination, each request must deliver 10 cards. For that reason MONGO DB or other Data Bases was created, take adventage of that. Is the best aproach, some day your app will be complex.

In anothe hand, the human eye isnt capable to watch such size of info... Please put your self in the shoes of the final user =)

Hector
  • 636
  • 8
  • 16