Closed Astra-RX closed 3 years ago
I'm not sure how or even whether react-virtuoso should solve this? I think this would be solvable inside the rendered component by rendering a 0 height div until the image is loaded. Then it would only render once with the loaded image.
But you would still have a rendering jump since the render would be coming in asynchronously after scroll. I had a similar problem in my app and my solution was to cache the known image sizes. Another approach could be to pre-load images in the background so that when the element comes into view the image is already cached.
Or am I missing an obvious solution I didn't think of?
@jmeistrich yes, these methods came out first too when I was thinking about this. I also took a look at Slack, texts and images were fixed height placeholders when they are loading, which is probably not very useful. The use case may be specific, but I think to support async load with callback on item renderer is a useful feature.
Btw, could you give me more detail on how to preload images without re-rendering? 0-height div sounds promising.
@Artoria-0x04 You can render an image with display: none and it will still load the image and fire the onLoad event. Then you can get the naturalWidth and naturalHeight (the original size of the image before the browser resizes it).
Or alternatively you can render the image inside a container with { height: 0, overflow: 'hidden' } and it well render normally but just not be visible. Then once it's loaded, remove that style and it will display normally.
I made a jsfiddle of both examples: http://jsfiddle.net/pgm13fen/1/
Thanks, I'll give it a try
A thing that might help in such case is the scroll seek mode behavior.
A thing that might help in such case is the scroll seek mode behavior.
This is not available on VirtuosoMessageList.
@mayurkalia99 I would not recommend having images with unknown size in the first place. There are several issues that describe the problem.
<Image className="max-h-[120px] max-w-[400px]" blurDataURL={file.file_url} src={file.file_url} width={120} height={400} alt={file.name} onClick={() => file && handleFileClick({ filename: file.name, url: file.file_url, fileType: file.type, }) } />
Using next/image like this, passing specific width and height.
Currently list items height are immediately determined and updated on resize. When rendering an image, the height is known after the image loaded, therefore the total height changes during scrolling and feels staggered.
How about introducing an onload callback for async rendering, or using the native onload perhaps?