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

[Feature request] Disable / control unmounting of already mounted rows #298

Closed
laggingreflex opened this issue Feb 17, 2021 · 6 comments
Closed
Labels
enhancement New feature or request

Comments

@laggingreflex
Copy link

Someone's made this feature request in bvaughn/react-window#234, I'd like to request it here as well.

I would like to suggest an option to control the unmounting of already mounted rows.
This could give a performance boost to lists with a moderate amount of large rows but which are very expensive to render.
If properly handled (rows should use memo of course) it would only render rows the first time they are visible and then keep them mounted to be able to scroll back to them again without needing to render them again.

The initial rendering of new react nodes (ie. nodes that were added or have a new key) is the most expensive part of react rendering - subsequent updates are way faster.
This is why I would love to see a library supporting virtual scrolling, but at the same time keeping already rendered components mounted (because as long as they don't exceed a quite large amount, this should be faster).

@laggingreflex laggingreflex added the bug Something isn't working label Feb 17, 2021
@petyosi petyosi added enhancement New feature or request and removed bug Something isn't working labels Feb 17, 2021
@petyosi
Copy link
Owner

petyosi commented Feb 17, 2021

This seems like a different kind of story than what Virtuoso is designed for, to be honest. Leaving the issue open for potential feedback, but my initial reaction is that I am unlikely to include such a mode.

@stephenh
Copy link
Contributor

stephenh commented Jun 3, 2021

Fwiw, we were initially surprised that neither react-window or react-virtuoso provided this sort of "caching" of "already rendered, then scrolled away, then scrolled back" nodes.

And that, in general, React itself seems to make this hard to implement (i.e. you'd need to trick the reconciler into keeping your DOM nodes around, probably by keeping them in the DOM but marked as display: none while "cached").

Specifically the use case where we cared/wanted this caching for was:

  • User loads 100 rows, with a kinda slow initial render but good enough
  • User type-ahead searches "foo", which filters down to 1 row (really fast because we're throwing away 99 DOM nodes and the last 1 is useMemo'd)
  • User clears their type-ahead search and we've totally forgotten the 99 DOM nodes that just got thrown away and have to re-build them, so we pay the "kinda slow initial render" cost again

So, this led to a weird type-ahead experience where it's very fast to filter down (useMemo'd rows aren't re-rendered), but noticeably slower to un-filter (regardless of useMemo usage, rows just don't exist anymore).

All of this said, I think now that we're on react-virtuoso, this is going to matter a lot less because we're never "rendering 100 rows" anyway, whether on the initial load or the un-filter-type-ahead case.

So, dunno, it does seem intellectually fancy to cache these sort of "I just rendered that, and now have to do it again" DOM nodes, and IMO wouldn't hurt for react-virtuoso to do so, but at least for us it is probably not going to matter in practice.

@NicoleMGF
Copy link

This would help for lists that include images. Having the images re-fetched for users with caching disabled every time they scroll is a big hit to page size.

@AdrianMrn
Copy link

AdrianMrn commented Oct 19, 2021

In my case, this would help with a list of dynamically sized items that control their own state, which has an effect on the height of the item (collapsible menus inside of a row).

Changing some state in 1 item will update the height of the list correctly, but as soon as you scroll down and the item unmounts, the height Virtuoso has in state is different from the actual height of the list, causing some weird jitters when scrolling back up.

I've managed to partially solve this by saving the state of those dynamic components outside of the Virtuoso tree, and reusing it when rendering the components again, but it would be nice if there was a way to do this out of the box and not have to rerender the item at all.

@petyosi
Copy link
Owner

petyosi commented Oct 19, 2021

I don't see a way to do that without either "breaking" virtualization or doing some hacks around React DOM management. For future comers - having stateful items inside the virtualized list is not the way to go, as they get unmounted/remounted. Lifting state up the component tree is the solution for that.

@JustynaKK
Copy link

Hello, does anybody found the hack for unmounting? my render are very 'expensive' so I would like to avoid rendering them from teh beginning over and over again while user is scrolling

Repository owner locked as resolved and limited conversation to collaborators Jun 7, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

6 participants