Thoughts on React.js
Last week, my cutting-edge web technologies class had the luxury of being lectured by one of the core contributors to the React.js project: Pete Hunt.
What is it? #
React is a JavaScript application framework that clearly abstracts user interface interactions by separating the rendering responsibilities that is powered by a virtual DOM diff.
Or as React’s website simply puts it:
A JavaScript library for building user interfaces
React isn’t the first framework to simplify developing JavaScript web applications. That being said, Pete’s lecture gave us a fundamental understanding on the primary advantages of React’s design over the design of otherJavaScript application frameworks.
To understand why React is so fundamentally different from other frameworks, we have to understand the problems that arise when using other application frameworks. Most JavaScript application frameworks base their implementation off of Key Value Observables (KVO). Some common issues you might encounter with the KVO-based application frameworks include:
- There’s a lot of interleaving in the code. When tinkering in frameworks like Ember.js and Angular.js, you could find yourself breaking abstraction barriers and accessing properties of certain elements in order get the correct interaction you’d like to see in your user interface.
- You’re unfortunately using string literals for accessors and directives. This has some poor implications on testing, especially in static type checking.
- The overhead of KVO typically grows linearly with the amount of data you’re modeling. However, although most web applications will have a lot of data modeled, you’ll typically only render a few hundred elements in the view for the user to interact with. This could imply that KVO will waste resources on tracking stuff that doesn’t necessarily matter.
Instead of keeping track of every single change as a chain of events, React uses the following model:
- React tracks snapshots of the entire DOM at a particular time
- React renders the page in a virtual DOM
- React takes the diff between the client’s DOM and the virtual DOM
- React applies the changes to the elements that have changed
What do I gain if I use React? #
React helps you to properly separate UI responsibilities from controller logic. Often times when developing in KVO-based frameworks, it’s difficult to enforce these abstractions properly. You can find yourself mangling accessor interactions in the view, the model, and/or even the controller. React helps enforce an abstraction that prevents interleaving responsibilities.
React’s proper abstraction enforcement not only simplifies the development process for better and more modular code, but also enables more robust testing. With other frameworks, testing can be difficult since accessors are often through string literals. In React, everything is JavaScript – which opens the door to static type checking.
Another fundamental advantage of React is that its data processing model scales well with large amounts of modeled data in a typical web application. The typical web application doesn’t display all it’s modeled data in the DOM; most commonly the top 10 or top 100 is presented in some interactive fashion. Traditional KVO-based frameworks have significant overhead while tracking changes (linear to the amount of data you have) and can have negative memory performance implications. This is especially detrimental to mobile devices which will simply crash if memory is over-utilized.
In contrast, the overhead required in maintaining UI interactions with React is linear to what’s being rendered in the DOM. React doesn’t do any book keeping to observe the data that it’s interacting with. Rather, the modeled data is just JavaScript, and the only book keeping is in re-rendering the changes in a virtual DOM (when triggered). Hence, if the application maintains some data models with million of entries, the overhead from React is still on the order of how many nodes are rendered in the DOM rather than on the order of how many items are present in our collection. This has huge implications on memory performance for typical web applications since the typical web application really doesn’t have that many nodes in the DOM.
Okay, but what do I lose? #
React is a great framework to use for a typical web application with a ton of changing data and a subset of visualizations. That being said, React isn’t perfect for everything.
React uses a lot more CPU to perform its diff between the virtual DOM and the current DOM. This has some major performance implications on realtime re-rendering of a lot of nodes in the DOM. If a lot of changes are happening in the DOM in rapid succession, the application will constantly be utilizing the CPU to perform these diffs – which could result in user interactions that aren’t as smooth as one would like.
The touted memory performance analysis of React, React’s overhead grows linearly with the size of your view, can also have negative performance implications on some unique use cases. In a web application that renders tons of nodes in the DOM, this would significantly cause the web application to at least double in memory usage to just perform a diff with the virtual DOM (since all the nodes need to be rendered in the virtual DOM).
An example of an application that would perform extremely poorly is an interactive visualization of large datasets in which all of the data needs to be represented multiple times in the DOM. Not only could realtime visual interactions be slowed down by the virtual DOM diffs, but also the memory requirements in rendering a virtual DOM for visualizing all the data could prove extremely costly in memory requirements for the application. Applications like this might be better off utilizing D3.js in organizing UI interactions.
Conclusions #
Pete’s lecture on the benefits of React have really helped inform me on when I should be using React for a web application project. I haven’t done much programming with React, but I foresee it being my “go to” framework for many of the common web applications I’ll end up developing.
Credits to Andrew Fang and Erica Yin on helping me write this post.