Why you should use Virtualization for Larger Lists
Recently i was working on office’s work and i found that my website was so slow and laggy because i was rendering 500 cards 🤭 then i did some research and i found virtualization technique so thought why not write an article about it.
What is Virtualization? 🤔
Virtualization is a powerful technique used in web development to improve performance, especially when rendering large datasets. Instead of rendering all items in a list at once which can be slow and resource intensive virtualization only renders the items that are visible within the user’s viewport. This drastically reduces the load on the browser and enhances the smoothness of the user experience. and trust me this technique improved my site’s performance by 40% 😳.
first try to understand through the diagram.
How Virtualization Works
The diagram above illustrates the efficient process of list virtualization:
-
The process begins when a user interacts with the list, triggering the virtualization mechanism.
-
The system continuously monitors for significant changes in scroll position.
-
When the scroll position changes, the system determines which items should be visible in the current viewport.
-
Only the data for items within the visible range is retrieved from the data source.
-
The system efficiently renders only the items that should be visible to the user.
-
As new items are rendered, those that have scrolled out of view are removed from the DOM to maintain performance.
-
The scroll position is updated to ensure a smooth and natural scrolling experience.
This continuous cycle optimizes performance by managing only the visible portion of the list, making it possible to handle large datasets smoothly and efficiently.
The highlighted steps (in pink, light blue, and light green) emphasize the most critical parts of the process: initiating the scroll, calculating the visible range, and rendering the visible items.
Why Use Virtualization? 😉
Virtualization offers several benefits:
- Improved Performance: By rendering only visible items, the application uses fewer resources, resulting in faster rendering and smoother scrolling.
- Reduced Memory Usage: With fewer DOM elements, the memory footprint of the application is significantly reduced.
- Better User Experience: Users can smoothly scroll through large datasets without experiencing lag or freezes.
- Scalability: Virtualization allows applications to handle extremely large datasets efficiently.
Implementing a Virtualized Image Gallery 💀
Let’s put theory into practice by building a virtualized image gallery using React and the react-virtualized
library. We’ll create a component that efficiently renders a large number of images.
First, install the necessary dependencies:
npm install react-virtualized
Okay now checkout this code
"use client"
import React, { useEffect, useState } from "react"
import { List, WindowScroller } from "react-virtualized"
import { useWindowSize } from "usehooks-ts"
import "react-virtualized/styles.css"
interface Image {
id: number
title: string
url: string
}
const ImageCard = ({ image }: { image: Image }) => (
<div className="my-4 flex h-44 items-center justify-center gap-4 sm:h-60 md:my-0 lg:h-72">
<img
src={image.url}
alt={image.title}
className="h-full w-full object-cover"
/>
</div>
)
export default function VirtualizedImageGallery() {
const [images, setImages] = useState<Image[]>([])
const [isLoading, setIsLoading] = useState(true)
const [columnCount, setColumnCount] = useState(1)
const [rowHeight, setRowHeight] = useState(300)
const { width = 0 } = useWindowSize()
useEffect(() => {
fetch("https://jsonplaceholder.typicode.com/photos")
.then((response) => response.json())
.then((data) => {
setImages(data.slice(0, 500))
setIsLoading(false)
})
}, [])
useEffect(() => {
if (width >= 1536) {
setColumnCount(5)
setRowHeight(360)
} else if (width >= 1024) {
setColumnCount(4)
setRowHeight(340)
} else if (width >= 768) {
setColumnCount(3)
setRowHeight(320)
} else if (width >= 640) {
setColumnCount(2)
setRowHeight(300)
} else {
setColumnCount(1)
setRowHeight(250)
}
}, [width])
if (isLoading) return <h1>Loading....</h1>
return (
<div className="flex flex-col gap-4 overflow-x-hidden">
<WindowScroller>
{({ height, isScrolling, scrollTop }) => (
<List
autoHeight
className="min-h-screen"
width={width}
height={height}
isScrolling={isScrolling}
rowCount={Math.ceil(images.length / columnCount)}
rowHeight={rowHeight}
rowRenderer={({ index, key, style }) => {
const rowImages = images.slice(
index * columnCount,
index * columnCount + columnCount
)
return (
<div
className={`grid grid-cols-1 p-4 gap-4 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 lg:px-10 2xl:grid-cols-5`}
key={key}
style={style}
>
{rowImages.map((image) => (
<ImageCard key={image.id} image={image} />
))}
</div>
)
}}
scrollTop={scrollTop}
/>
)}
</WindowScroller>
</div>
)
}
Let’s break down the key components of this implementation:
- WindowScroller: This component from
react-virtualized
allows the list to scroll with the window, providing a seamless experience. - List: The main virtualized component that efficiently renders only the visible rows.
- Responsive Design: We use the
useWindowSize
hook to adjust the number of columns and row height based on the screen width, ensuring a responsive layout. - rowRenderer: This function is called for each visible row, rendering a grid of images for that row.
- ImageCard: A simple component to display each image with consistent styling.
See the above code is just for the your reference. I know you can do better than this .☘︎ ݁˖.
The WindowScroller
is very useful component you should checkout the
react-virtualized
official site it’s highly recommended.
Conclusion 👀
By implementing virtualization in our image gallery, we’ve created a component that can efficiently handle hundreds or even thousands of images while providing a smooth, responsive user experience. I hope you learned something new today.
Enjoy ⋆.˚🦋༘⋆..
Comments
Leave a comment or reaction below!