Rico Kahler I’m a React engineer at www.justsift.com. At Sift, I’m responsible for taking the team’s ideas and designs and turning them into experiences.

Windowing wars: React-virtualized vs. react-window

4 min read 1215

React Virtualized Versus React Window

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 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? 🚀

LogRocket Free Trial Banner

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.

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.

As a reminder, React internally uses a “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.

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:

No windowing Windowing
Initial load time ⚠️ Depends on the list size ✅ (near) Instant
List item load time ✅ (near) Instant ⚠️ Depends on complexity of the item
DOM manipulation occurs ⚠️ On initial render ⚠️ On scroll

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 😓.

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 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:

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:

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

Virtualized collection types:

Helpers/decorators for the above collection types:

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)

Dynamic item sizing (CellMeasurer)

Note: there are some caveats to the approach in the demo above (as there are caveats to using the actual CellMeasurer in react-virtualized).

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 package:

Arrow key navigation (ArrowStepper)

Scroll-synced multigrids (MultiGrid + ScrollSync)

Question 4: Should you use react-virtualized anyway?

Quoting from the react-window GitHub 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)! 🙂

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: , a DVR for web apps

LogRocket is a frontend application monitoring solution 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.

.

Rico Kahler I’m a React engineer at www.justsift.com. At Sift, I’m responsible for taking the team’s ideas and designs and turning them into experiences.

One Reply to “Windowing wars: React-virtualized vs. react-window”

  1. “Without windowing, React has to write your entire list to the DOM before one list item is visible.” This statement although correct is not the entire reason why one should use a virtualized list, imho scrolling is the main reason here. Scrolling a dom list with thousands of nodes feels like you’ll die of old age before you get to the other side.

Leave a Reply