Frontend Development 16 min read

Implementing Fixed, Variable, and Dynamic Height Virtual Lists with React‑Window

This article explains how to build three kinds of virtual scrolling lists—fixed‑height, variable‑height, and dynamic‑height—using React‑Window, covering core principles, detailed implementation code, performance considerations, and practical tips for handling irregular item sizes.

Rare Earth Juejin Tech Community
Rare Earth Juejin Tech Community
Rare Earth Juejin Tech Community
Implementing Fixed, Variable, and Dynamic Height Virtual Lists with React‑Window

Introduction

While working with large data sets in React, virtual scrolling is essential for performance. Using react-window as a base, this guide demonstrates three virtual list patterns: fixed item height, variable item height, and dynamic item height.

Virtual List Core Principle

The list is divided into three zones: an upper buffer, the visible window, and a lower buffer. When an item leaves the visible area, it is removed from the upper buffer and a new item is added to the lower buffer, keeping the total number of rendered elements constant.

Implementation

1. Fixed‑Height Virtual List

Usage

const Row = ({ index, style, forwardRef }) => {
  return (
{`Row ${index}`}
);
};

const App = () => {
  return (
{Row}
);
};

Implementation Details

1) Compute the total container height for 1000 items. 2) Derive the start index of the visible area, the start index of the upper buffer, and the end index of the lower buffer. 3) Position each rendered item absolutely using its calculated top value.

2. Variable‑Height Virtual List

Usage

const rowSizes = new Array(1000).fill(true).map(() => 25 + Math.round(Math.random() * 55));
const getItemSize = index => rowSizes[index];

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

const App = () => (
{Row}
);

Because each item has a random height, the total container height cannot be computed directly. Instead, the algorithm estimates a sufficiently large container and calculates the top of each rendered item by accumulating the heights of preceding items.

Key Challenges and Solutions

Unknown total height – use an over‑estimated container.

Cannot compute top via index * itemSize – accumulate actual heights.

Scroll offset does not map to an index directly – iterate forward from the last measured item until the accumulated offset exceeds the scroll offset.

3. Dynamic‑Height Virtual List

Usage

const items = [];
const itemCount = 1000;
for (let i = 0; i < itemCount; i++) {
  const height = 30 + Math.floor(Math.random() * 30);
  const style = { height, width: '100%' };
  items.push(
Row {i}
);
}

const Row = ({ index }) => items[index];

const App = () => (
{Row}
);

In this variant the itemSize prop is omitted; the list learns each item's height after it is rendered. A ResizeObserver watches size changes and updates the cached metadata, then forces a re‑render.

Supporting Components

class ListItem extends React.Component {
  constructor(props) {
    super(props);
    this.domRef = React.createRef();
    this.resizeObserver = null;
  }
  componentDidMount() {
    if (this.domRef.current) {
      const domNode = this.domRef.current.firstChild;
      const { index, onSizeChange } = this.props;
      this.resizeObserver = new ResizeObserver(() => {
        onSizeChange(index, domNode);
      });
      this.resizeObserver.observe(domNode);
    }
  }
  componentWillUnmount() {
    if (this.resizeObserver && this.domRef.current.firstChild) {
      this.resizeObserver.unobserve(this.domRef.current.firstChild);
    }
  }
  render() {
    const { index, style, ComponentType } = this.props;
    return (
);
  }
}

The full implementation combines the metadata helpers ( estimatedHeight , getItemMetaData , getStartIndex , getEndIndex , getRangeToRender ) with the ListItem component to achieve smooth scrolling even when items resize dynamically.

Conclusion

React‑Window only provides fixed‑height and variable‑height lists; the dynamic‑height version is built by extending the variable‑height logic and adding resize observation. Understanding the buffer zones and offset calculations allows developers to hand‑craft efficient virtual lists for any item‑size pattern.

For the complete source code, visit the repository at https://gitee.com/zhutouqietuzai/virtual-list .

PerformanceJavaScriptreactvirtual-list
Rare Earth Juejin Tech Community
Written by

Rare Earth Juejin Tech Community

Juejin, a tech community that helps developers grow.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.