Skip to content

Latest commit

 

History

3 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

React Virtualization Demo

A small React app for learning list virtualization with react-window.

Prerequisites

  • Node.js 18+ (installed via Homebrew: brew install node)

Commands

cd react-virtualization-demo
npm install    # first time only
npm run dev    # start dev server → open the URL shown in the terminal

Project layout

  • src/App.jsx — virtualized 3-column grid of 100 movie cards
  • src/components/MovieCard.jsx — single card (poster placeholder + title/meta)

React Window Virtualization Guide

A beginner-friendly explanation of virtualization using react-window.


What is Virtualization?

Virtualization is a performance optimization technique where only visible UI elements are rendered in the DOM instead of rendering the entire dataset.

Example:

  • Instead of rendering 10,000 cards,
  • only visible cards are rendered,
  • and new cards are mounted dynamically during scroll.

Benefits

  • Smaller DOM
  • Faster rendering
  • Smooth scrolling
  • Lower memory usage

Popular Libraries

  • react-window
  • react-virtualized

What is List?

import { FixedSizeList as List } from "react-window";

List is the virtualization engine.

It acts like a smart scroll container.

Responsibilities

  • Detect visible rows
  • Render only visible rows
  • Remove non-visible rows
  • Handle scrolling efficiently
  • Calculate row positions

What is Row?

const Row = ({ index, style }) => {

Row is a reusable component responsible for rendering one horizontal row.

Example:

  • If each row contains 3 movie cards,
  • then one Row renders 3 movies.

Visual Structure

--------------------------------
| Movie 1 | Movie 2 | Movie 3 |
--------------------------------

Each horizontal strip is one row.


Why Row Receives style

const Row = ({ index, style })

react-window automatically passes a style object to every row.

Example:

{
  position: "absolute",
  top: 580,
  left: 0,
  height: 580,
  width: "100%"
}

These styles are NOT mainly for visual styling.

They are required for virtualization because:

  • rows are manually positioned,
  • not naturally stacked by browser layout.

Important Properties

  • position: absolute
  • top
  • height
  • width

Without these styles:

  • rows overlap,
  • scrolling breaks,
  • virtualization fails.

Why ...style Is Required

style={{
  ...style
}}

This copies all styles provided by react-window.

Equivalent to:

position: style.position,
top: style.top,
height: style.height,
width: style.width

Without spreading the style:

  • rows render at same position,
  • virtualization positioning fails.

Why Rows Use position: absolute

Normally browser stacks elements naturally:

Row 1
Row 2
Row 3

But virtualization manually positions rows for performance.

Example:

{
  position: "absolute",
  top: 1160
}

This means:

  • place this row exactly at 1160px from top.

Understanding top

top tells browser where the row should appear vertically.

Formula

top = rowIndex * itemSize

Example

Row top
0 0
1 580
2 1160

Understanding height

height: 580

Defines vertical space occupied by each row.

Needed for:

  • scrolling calculations
  • visible row detection
  • positioning

Understanding width

width: "100%"

Makes row occupy full container width.


Understanding itemCount

itemCount={Math.ceil(MOVIES.length / COLUMN_COUNT)}

itemCount means:

  • total number of rows,
  • NOT total number of movies.

Example

  • 100 movies
  • 3 movies per row

Calculation

Math.ceil(100 / 3)

Result

34 rows

So List internally thinks:

Row 0
Row 1
Row 2
...
Row 33

What List Does With itemCount

Using:

itemCount = 34
itemSize = 580

It calculates total scroll height:

34 * 580 = 19720px

This creates a natural scrollbar even though only visible rows are rendered.


Understanding itemSize

itemSize={580}

Means:

  • every row height is fixed to 580px.

This is extremely important.

List uses this to:

  • calculate row positions,
  • detect visible rows,
  • optimize rendering.

Formula

top = rowIndex * itemSize

How List Detects Visible Rows

Suppose:

scrollTop = 1200
itemSize = 580

Calculation

1200 / 580 ≈ row 2

So:

  • Row 2 is visible,
  • render Row 2 onward.

Only visible rows stay mounted.


Why Fixed Height Is Important

Because rows have fixed height:

  • List can calculate positions mathematically,
  • without measuring actual DOM elements.

This makes virtualization extremely fast.


Understanding This Code

<div
  style={{
    ...style,
    height: style.height - 20,
    paddingBottom: "20px",
    boxSizing: "border-box",
  }}
>

Why height: style.height - 20

Suppose original height:

580

Now reduced to:

560

This creates spacing between rows.


Why paddingBottom: 20px

Adds bottom spacing visually.

Without reducing height first:

  • total row size becomes incorrect,
  • virtualization calculations break.

So:

  • reduce height,
  • then add padding.

Final visual size remains correct.


Why boxSizing: border-box

Normally:

final height = content + padding

With border-box:

  • padding stays inside defined height.

This keeps row size accurate.


Understanding List Props

<List
  height={window.innerHeight - 140}
  itemCount={34}
  itemSize={580}
  width={"100%"}
>
  {Row}
</List>

height

Visible viewport height.

Example

window.innerHeight = 900
height = 760

Meaning:

  • only 760px visible,
  • remaining content scrolls.

itemCount

Total number of rows.

Example

34 rows

itemSize

Fixed height of each row.

Example

580px

width

Width of virtualized container.

Example

100%

{Row}

This is the row renderer component.

Internally List does:

<Row index={0} style={...} />
<Row index={1} style={...} />

Only for visible rows.


Virtualization Procedure Summary

  1. Create a Row component.

  2. Each row is responsible for rendering a group of items, such as 3 movie cards per row.

  3. react-window passes a style object to every row.

  4. That style contains positioning properties like:

    • absolute positioning
    • top
    • height
    • width
  5. These styles are required for virtualization because they help react-window correctly position rows inside the scroll container.

  6. Inside the row:

    • slice() is used to get items belonging to that row,
    • map() is used to render those items.
  7. Then the List component from react-window is used.

  8. List acts as a virtualized scroll container.

  9. It receives props like:

    • height
    • itemCount
    • itemSize
    • width
  10. List continuously checks which rows are currently visible inside the viewport.

  11. Only visible rows are mounted in the DOM.

  12. When the user scrolls:

  • rows leaving the viewport are unmounted,
  • new visible rows are mounted dynamically.
  1. This keeps the DOM small and improves rendering and scrolling performance significantly.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages