React and the DOM

Avatar

Share

Β β€’Β 

22 days ago

Β β€’Β 

View on Twitter

Whenever I hit a problem with React its because I don't have a solid understanding of how it really works. Here's a brief explainer:

To understand how React works we actually need to understand the problem it was designed to solve. Imagine it's 2013 and you want to make a banner appear when a user clicks a button just using JS.

You need to do three things - listen for an event on the button - find the place in the DOM you want to add the banner - create the banner and update the DOM at that point.

Here's the catch - every time you update the DOM it causes a UI reflow as the browser paints the new tree structure. These reflows are a little bit slow so you want to keep them to a minimum.

But in an app with lots of interactivity you don't have any control over when and how often these reflows happen. Two reflows could happen one after the other and lock up the UI momentarily.

React has a clever solution: it stores a copy of the DOM in your browser's memory. This is referred to as the virtual DOM and it is the core of what makes React (relatively) fast.

Any changes to your app are captured by React and applied to this virtual DOM first. These changes are fast because they are happening virtually and not causing any UI reflows.

React then compares the new version of the DOM to the current version (still happening in memory). This process is called diffing and they use a whole bunch of clever tricks to work out what exactly has changed.

Each part of the tree that has changed is marked as dirty and typically so are all of its children. These changes are then all batched together and applied at once.

The beauty here is that only the necessary DOM updates are made and they are made at a reliable point in the cycle. But it isn't magic.

One pitfall is that you can occasionally do things that unintentionally mark components as dirty causing whole portions of the tree to be re-rendered unnecessarily.

This might not seem like a big deal but remember that this virtual DOM creation process re-executes your components. Function calls, variable declarations, looping over arrays etc all gets re-executed.

This performance hit adds up over time in a "death by a thousand paper cuts" sort of way. This is why we have tools like memo in React - they provide more information to React about whether a certain component should be updated

Other frameworks like Svelte and Solid just opt out of all this hassle by not using a virtual DOM at all and instead using some compiler wizardry.

Anyway, that's kinda it. This thread was actually inspired by this tweet https://twitter.com/brian_lovin/status/1561883657865834496?s=20&t=EeAlN-IHMlxF9d6__D0_fg