-
-
Notifications
You must be signed in to change notification settings - Fork 4.2k
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
Manually mount slots #6360
Comments
How much faster is it implementing vitual scrolling with this technique ? If it is significantly faster then this might be worth pursuing IMO. |
@johnoscott Definitely a noticeable difference. I've found this effect in pretty much every virtual list I've seen, but never once in VSCode. |
That depends entirely on the implementation. I've been able to create incredibly smooth virtual scrolling for fixed height items. It's definitely possible with Svelte. Could you share an absolute minimal REPL?
From the screenshot I don't think that description is accurate. The order very much matters. I think it never appends new elements. It intelligently re-uses items and put them back at the top/bottom when they leave the viewport. That's absolutely possible with Svelte and just a matter of intelligently shifting your array slice. If you look at the value of |
@Prinzhorn Haven't seen a single Svelte virtual list without this. Here are the first 3 I found on Google:
Here's a screenrecording showing that it does add and remove elements when you scroll: Screen.Recording.2021-05-28.at.3.22.10.PM.mp4 |
I'll take this back partially. It seems to depend on the browser and I don't know if manually mounting slots changes anything about that. Updating things while scrolling has always had slight delays on certain browsers. The only thing you can do is have enough leeway (additional items at the top and bottom outside the viewport) so that it is not noticeable any longer. VSCode (or monaco rather) does not count, because it's entirely virtual (the scrollbar is not native, so they can control the rendering 100%). You can see that the parent of those items is moved as well to achieve the actual scrolling. It's also stepped scrolling, not smooth scrolling. So way less updates. Here's a video of my implementation that re-uses items. In Firefox (video) there is slight delay of rendering new items. In Chromium it's super smooth. vokoscreen-2021-05-28_19-42-29.mp4 |
@Prinzhorn Ah, I see that VSCode doesn't use normal scrolling, good observation. Adding a buffer does indeed help quite a bit, but only partially (had tried that before opening this issue). For simple lists, using a buffer should be fine. How did you go about implementing that? I've only tested this on Chromium, so if you say it's super smooth then that's promising for sure. |
@probablykasper I can't extract this from my code base rn, but the idea is to not key your each so that the elements are re-used. And then you need to shift your array slice over and translate the items that are now in the "wrong" place. But I think this still doesn't solve your original issue, because my implementation also lags slightly in Firefox. That's something native scrolling will always suffer from in one way or another (I've done my fair share of scrolling animations). If you need full control then you need virtual scrolling which comes with it's own issues and usually worse UX. |
@Prinzhorn Been trying to figure it out for a while, but really not sure how it would be done. The way I tried to do it is this: {#each Array(visibleCount) as _, i}
<slot
item={getItem(visibleIndexes[i])}
index={visibleIndexes[i]}
pos={visibleIndexes[i] * itemHeight} />
{/each} Then, I for example run |
@probablykasper I extracted it from my code base https://github.com/Prinzhorn/better-svelte-virtual-list
REPL thinks it's an endless loop with 1 million rows |
@Prinzhorn Thanks for sharing it. I tried it out, but that too seems to rerun For now I'm caching the values in an array, that seems like the best that can be done currently |
I don't see a problem with that. It's just a property lookup in my case ( Edit: The alternative (with keyed each) is that you get constant |
@Prinzhorn The problem is the extra code/complexity of having to manually implement a cache |
Here's a REPL showing the issue: |
Is your feature request related to a problem? Please describe.
I have a virtual list component
VirtualList
where it takes a little time to load each item, so that this effect is quite prevalent when scrolling:xScreen.Recording.2021-05-24.at.2.25.20.AM.mp4
I imagine the issue here is that whenever a new item becomes visible, all visible items are re-rendered.
Describe the solution you'd like
The fastest virtual list I've seen is VSCode's. It works by appending new elements to the view without being concerned about what order they're in, and positioning them using
position: absolute
:The best way I can see to accomplish this is to be able to manually mount Svelte slots from JS.
Another possible solution would be to have an
#each
block where you could add or remove items without re-rendering any items.Describe alternatives you've considered
Container
component and theItem
components (keyboard events, drag-and-drop events, row selection), as well as sharing styles between them. Keeping slots would be great.<svelte:options immutable/>
, but doesn't seem like something that would work here.How important is this feature to you?
Quite important, but I understand it's an edge case.
The text was updated successfully, but these errors were encountered: