Windowing wars: React-virtualized vs. react-window
Tags: react
Published: 2019-07-08 20:14:26

---
title: Windowing wars: React-virtualized vs. react-window
published: true
tags: react
canonical_url: https://blog.logrocket.com/windowing-wars-react-virtualized-vs-react-window/
---

![](https://thepracticaldev.s3.amazonaws.com/i/u2pco96e3ce581ttn5qy.jpg)

> `react-window` is a complete rewrite of `react-virtualized`. I didn’t try to solve as many problems or support as many use cases. Instead I focused on making the package smaller and faster. I also put a lot of thought into making the API (and documentation) as beginner-friendly as possible.

The above is quoted directly from the [`react-window` GitHub](https://github.com/bvaughn/react-window#how-is-react-window-different-from-react-virtualized) by Brian Vaughn, aka `bvaughn` — the author of both `react-window` and `react-virtualized` (and also a member of the React core team).

**TL;DR** : `react-window` is newer, faster, and much lighter, but it doesn’t do everything `react-virtualized` can do. Use `react-window` if you can, but `react-virtualized` has a lot of bells and whistles that might be pretty useful to you.

In this article, we’ll cover:

1. What do these libraries do?
2. What does `react-window` do?
3. What does `react-virtualized` do that `react-window` doesn’t do?
4. Which one is best for you? ![🚀](https://s.w.org/images/core/emoji/12.0.0-1/72x72/1f680.png)

### [![LogRocket Free Trial Banner](https://i0.wp.com/blog.logrocket.com/wp-content/uploads/2017/03/f760c-1gpjapknnuyhu8esa3z0jga.png?resize=1200%2C280&ssl=1)](https://logrocket.com/signup/)

### Question 1: Do you need windowing?

Both react-window and `react-virtualized` are libraries for windowing.

**Windowing** (aka virtualizing) is a technique for improving the performance of long lists by only writing the visible portion of your list to the [DOM](https://developer.mozilla.org/en-US/docs/Web/API/Document_Object_Model/Introduction).

Without windowing, React has to write your entire list to the DOM before one list item is visible.

So if I had around 10,000 list items, I’d have to wait for React to write at least 10,000 `<div />`s to the DOM before the first item in that list is visible.

Ouch.
{% codesandbox 9zqowllmo %}
As a reminder, React internally uses a “[virtual DOM](https://reactjs.org/docs/faq-internals.html#what-is-the-virtual-dom)” to hold your UI state because the “real” DOM is slow and expensive. By windowing, you can speed up your initial render by avoiding the “real” DOM as much as possible.

### Question 2: Do you really need windowing?

Though it can improve performance, windowing is not a silver bullet.

Windowing improves performance because it delays writing your entire list to the DOM, but the reality is that those items have to be written to the DOM eventually if you want the user to see them. If you don’t pay for the rendering time upfront, then you’ll have to pay for it later.

Sometimes windowing can actually decrease perceived performance because the user has to wait for each individual list item to load on scroll instead of waiting for one eager load of the entire list on mount.
{% codesandbox ryy8pk8wqp %}
In the demo above, notice how the list in the windowed version appears faster, but the non-windowed version feels faster when you’re scrolling through it.

The windowed version appears faster because it delays rendering the whole list, but it feels slower/looks janky when scrolling fast because it’s loading and unloading list items to the DOM.

Whether or not to window greatly depends on your situation and what’s important to you:

<table>
<tbody>
<tr>
<td></td>
<td><b>No windowing</b></td>
<td><b>Windowing</b></td>
</tr>
<tr>
<td><b>Initial load time</b></td>
<td><span style="font-weight: 400;"><img draggable="false" class="emoji" alt="⚠️" src="https://s.w.org/images/core/emoji/12.0.0-1/svg/26a0.svg" scale="0"> Depends on the list size</span></td>
<td><span style="font-weight: 400;"><img draggable="false" class="emoji" alt="✅" src="https://s.w.org/images/core/emoji/12.0.0-1/svg/2705.svg" scale="0"> (near) Instant</span></td>
</tr>
<tr>
<td><b>List item load time</b></td>
<td><span style="font-weight: 400;"><img draggable="false" class="emoji" alt="✅" src="https://s.w.org/images/core/emoji/12.0.0-1/svg/2705.svg" scale="0"> (near) Instant</span></td>
<td><span style="font-weight: 400;"><img draggable="false" class="emoji" alt="⚠️" src="https://s.w.org/images/core/emoji/12.0.0-1/svg/26a0.svg" scale="0"> Depends on complexity of the item</span></td>
</tr>
<tr>
<td><b>DOM manipulation occurs</b></td>
<td><span style="font-weight: 400;"><img draggable="false" class="emoji" alt="⚠️" src="https://s.w.org/images/core/emoji/12.0.0-1/svg/26a0.svg" scale="0"> On initial render</span></td>
<td><span style="font-weight: 400;"><img draggable="false" class="emoji" alt="⚠️" src="https://s.w.org/images/core/emoji/12.0.0-1/svg/26a0.svg" scale="0"> On scroll</span></td>
</tr>
</tbody>
</table>

In general, I would not recommend windowing if you don’t have to. I’ve made the mistake of windowing when it was unnecessary, and the end result was a slower list that took longer to make and was significantly more complex. ![😓](https://s.w.org/images/core/emoji/12.0.0-1/72x72/1f613.png)

Both `react-window` and `react-virtualized` are great libraries that make windowing as easy as can be, but they also introduce a bit of constraints on your UI.

Before you window, try making your list normally and see if your environment can handle it. If you’re having performance issues, then continue on.

### Question 3: Is `react-window` good enough for you?

As [stated by the author](https://github.com/bvaughn/react-window#how-is-react-window-different-from-react-virtualized) of both `react-window` and `react-virtualized`:

> `react-window` doesn’t solve as many problems and doesn’t support as many use cases.

This might make you think `react-window` won’t solve your problem, but that’s not necessarily the case. `react-window` is a just a lighter core with a simpler philosophy.

`react-window` can still support many of the same use cases as `react-virtualized`, but it’s your responsibility as a developer to use `react-window` as a building block instead of `react-virtualized` for every use case.

`react-window` is just a library that virtualizes lists and grids. That’s why it’s more than 15 times smaller. [Quoting `bvaughn` again](https://github.com/bvaughn/react-window#how-is-react-window-different-from-react-virtualized):

> Adding a `react-virtualized` list to a [create-react-app] project increases the (gzipped) build size by ~33.5 KB. Adding a `react-window` list to a CRA project increases the (gzipped) build size by <2 KB.

Out of the box, `react-window` only has four components:

- [`FixedSizeList`](https://react-window.now.sh/#/api/FixedSizeList)
- [`VariableSizeList`](https://react-window.now.sh/#/api/VariableSizeList)
- [`FixedSizeGrid`](https://react-window.now.sh/#/api/FixedSizeGrid)
- [`VariableSizeGrid`](https://react-window.now.sh/#/api/VariableSizeGrid)

This is vastly different from the 13 components `react-virtualized` has.

Virtualized collection types:

- [`Collection`](https://bvaughn.github.io/react-virtualized/#/components/Collection)
- [`Grid`](https://bvaughn.github.io/react-virtualized/#/components/Grid)
- [`List`](https://bvaughn.github.io/react-virtualized/#/components/List)
- [`Masonry`](https://bvaughn.github.io/react-virtualized/#/components/Masonry)
- [`Table`](https://bvaughn.github.io/react-virtualized/#/components/Table)

Helpers/decorators for the above collection types:

- [`ArrowKeyStepper`](https://bvaughn.github.io/react-virtualized/#/components/ArrowKeyStepper)
- [`AutoSizer`](https://bvaughn.github.io/react-virtualized/#/components/AutoSizer)
- [`CellMeasurer`](https://bvaughn.github.io/react-virtualized/#/components/CellMeasurer)
- [`ColumnSizer`](https://bvaughn.github.io/react-virtualized/#/components/ColumnSizer)
- [`InfiniteLoader`](https://bvaughn.github.io/react-virtualized/#/components/InfiniteLoader)
- [`MultiGrid`](https://bvaughn.github.io/react-virtualized/#/components/MultiGrid)
- [`ScrollSync`](https://bvaughn.github.io/react-virtualized/#/components/ScrollSync)
- [`WindowScroller`](https://bvaughn.github.io/react-virtualized/#/components/WindowScroller)

As a general rule of thumb, you should be able to use `react-window` in place of `react-virtualized` for tables, lists, and grids. However, you can’t use `react-window` for anything else, including masonry layouts and any other 2-D layouts that don’t fit a grid.

Here are some demos of using `react-window` to achieve the same results as `react-virtualized`:

#### Dynamic container sizing (`AutoSizer`)
{% codesandbox 2zpo8nl56j %}
#### Dynamic item sizing (`CellMeasurer`)
{% codesandbox yw4ok6l69z %}
<iframe style="width: 100%; height: 500px; border: 0; border-radius: 4px; overflow: hidden;" title="Cell measurer demo" src="https://codesandbox.io/embed/yw4ok6l69z?fontsize=14" sandbox="allow-modals allow-forms allow-popups allow-scripts allow-same-origin"></iframe>

**Note:** there are some caveats to the approach in the demo above ([as there are caveats to using the actual `CellMeasurer` in `react-virtualized`](https://github.com/bvaughn/react-virtualized/blob/master/docs/CellMeasurer.md#limitations-and-performance-considerations)).

This cell measurer has to render the contents of the item twice: once to size it, and then once inside the list. This approach also requires the node to be rendered synchronously with react-dom, so complex list items may seem to appear slower when scrolling.

#### Infinite loading (`InfiniteLoader`)

Taken directly from the [`react-window-infinite-loader`](https://github.com/bvaughn/react-window-infinite-loader) package:
{% codesandbox 5wqo7z2np4 %}
#### Arrow key navigation (`ArrowStepper`)
{% codesandbox x9739j5v8q %}
#### Scroll-synced multigrids (`MultiGrid` + `ScrollSync`)
{% codesandbox h2g26 %}
### Question 4: Should you use `react-virtualized` anyway?

Quoting from the [`react-window` GitHub](https://github.com/bvaughn/react-window#how-is-react-window-different-from-react-virtualized) again:

If `react-window` provides the functionality your project needs, I would strongly recommend using it instead of `react-virtualized`. However, if you need features that only `react-virtualized` provides, you have two options:

1. Use `react-virtualized`. (It’s still widely used by a lot of successful projects!)
2. Create a component that decorates one of the `react-window` primitives and adds the functionality you need. You may even want to release this component to npm (as its own, standalone package)! ![🙂](https://s.w.org/images/core/emoji/12.0.0-1/72x72/1f642.png)

So there’s that!

`react-virtualized` is still a great project, but it may do more than you need. However, I would recommend using `react-virtualized` over `react-window` if:

1. **You’re already using `react-virtualized` in your project/on your team.** If it ain’t broke, don’t fix it — and, more importantly, don’t introduce unnecessary code changes.
2. **You need to virtualize a 2-D collection that is not a grid.** This is the only use case that `react-virtualized` handles that `react-window` has no support for.
3. **You want a pre-built solution.** `react-virtualized` has code demos for all its use cases while `react-window` just provides virtualized list primitives so you can build off them. If you want docs and pre-made examples with more use cases, then the heavier `react-virtualized` is for you.

### Bottom line

**`react-window`** : newer and faster virtualized list primitives. Use `react-window` as your virtualized list building block to satisfy your specific use case without bringing a lot of unnecessary code.

**`react-virtualized`** : a heavier all-in-one that solves — and provides docs/examples for — many use cases, including virtualizing collections that are not grids (e.g., masonry layouts). `react-virtualized` is still a great library but probably does more than you need it to.
* * *
### Plug: [LogRocket](https://logrocket.com/signup/), a DVR for web apps

[![LogRocket Dashboard Free Trial Banner](https://i2.wp.com/blog.logrocket.com/wp-content/uploads/2017/03/1d0cd-1s_rmyo6nbrasp-xtvbaxfg.png?resize=1200%2C677&ssl=1)](http://logrocket.com/signup/)

[LogRocket](https://logrocket.com/signup/) is a frontend logging tool that lets you replay problems as if they happened in your own browser. Instead of guessing why errors happen, or asking users for screenshots and log dumps, LogRocket lets you replay the session to quickly understand what went wrong. It works perfectly with any app, regardless of framework, and has plugins to log additional context from Redux, Vuex, and @ngrx/store.

In addition to logging Redux actions and state, LogRocket records console logs, JavaScript errors, stacktraces, network requests/responses with headers + bodies, browser metadata, and custom logs. It also instruments the DOM to record the HTML and CSS on the page, recreating pixel-perfect videos of even the most complex single-page apps.

[Try it for free](https://logrocket.com/signup/).
* * *
The post [Windowing wars: React-virtualized vs. react-window](https://blog.logrocket.com/windowing-wars-react-virtualized-vs-react-window/) appeared first on [LogRocket Blog](https://blog.logrocket.com).