5 ms·
You create a virtual list, only rendering the items visible in the viewport. Use intersection observer or scroll events to find out when you're about to go past
by TheAceOfHearts 9y ago
You create a virtual list, only rendering the items visible in the viewport. Use intersection observer or scroll events to find out when you're about to go past the selected item.
- amelius 9y agoDoesn't that cause either stuttering, or flickering in the viewport?
- jaggederest 9y agoWhen I did this back before ajax was a thing, it was by using image elements that were moved like a treadmill, we managed those so that there was a buffer outside the screen area that was pre-filled to avoid stuttering. Essentially we rendered ~1.5 screens wide / long and would fill them in a non-blocking way when the buffer was reduced.
- amelius 9y agoBut when you click the scrollbar and drag it down, you can easily make the viewport scroll by more than 2x its height in a matter of milliseconds. I experimented with this myself, and the UI designer I worked with thought it was not pretty when the screen turned blank while scrolling rapidly. The problem I had was that painting the items in the viewport took already more time than the allotted time per frame.
- Groxx 9y agoSome implementations provide placeholders that are quick to render (e.g. a single static image, no deep DOM/view tree) to work around this kind of thing. In my experience on both android and web it tends to work pretty well - even very low-end hardware can do this quickly enough to be invisible, and if you are able to drop down into something that can do instanced rendering it's about as close to "free" as possible. Whether the placeholders look any good is a different issue. We generally thought they looked / transitioned to real content a lot worse than showing nothing, and eventually just ripped them out. But e.g. Pinterest did it fairly successfully for a long time (they tended to replace images with a solid image-background-color so the content just kinda emerged. neat effect, but works far better with product images than user-generated content :) ) But ultimately, when you exceed your tolerances, you have to render something or nothing, or disallow it (e.g. block everything). You just have to choose which one. The point where you exceed will shift depending on what you're using/doing, but it always exists.
- darkmarmot 9y agoThis means the code has issues. I have virtualized data grids holding thousands of records with each cell incorporating d3 visualizations and this does not happen.
- ridiculous_fish 9y agoDo you have a link you can share?
- TheAceOfHearts 9y agoreact-virtualized [0] is a great implementation of a virtualized list using ReactJS. [0] https://bvaughn.github.io/react-virtualized/#/components/List https://bvaughn.github.io/react-virtualized/#/components/Lis...
- jaggederest 9y agoWell, we fixed that by not having a scrollbar! You had to click-and-drag to move the viewport, and thus it was difficult to move it more than ~1 screen width at a time.
- TheAceOfHearts 9y agoThis problem exists on native apps as well. There's multiple strategies for handling that, depending on your constraints and requirements. The simplest solution might be to use a placeholder. You might also want to track how much time has passed, so you can stay at 60FPS.
- TheAceOfHearts 9y agoIt depends on your implementation. This isn't a new problem, it also exists in native applications. If it takes a long time to render each item, you might consider using a placeholder and caching existing elements. Be sure to track how much time is spent rendering so you run at 60FPS.