All the buzz on Hacker News these first few months of 2015 has been centered around Facebook’s React library and Flux paradigm. I got the itch to try them out on a sample project, and learned a few things along the way. By no means am I a React or Flux expert. I’m still in the process of figuring out everything these two can provide to front end developers.
This blog post, as well as the presentation I’m giving at DevCon 5, is the culmination of my experiences using these two, and where I feel they fit into modern front end web development.
The most common goal I’ve come across in the applications we help write at Keyhole is maintainability. The applications we help write are expected to live for five, 10, or even 15 years after they go to production. They need to be written in such a way that a support team can come in once active development is done, and keep the product up and running for as long as necessary.
The experience I’ve had with React leads me to believe that Facebook wrote it with a different set of goals in mind. There are a lot of opinions on what that goal exactly is, so I’ll pull what I think they are straight from the horse’s mouth:
Just the UI: Lots of people use React as the V in MVC.
Virtual DOM: React abstracts away the DOM from you, giving a simpler programming model and better performance…
Data Flow: React implements one-way reactive data flow…
Those three points can be boiled down to performance. Facebook lives and dies by how quickly their web app loads. Longer load times leads to unhappy users, and unhappy users are a sub-optimal target for ads, and fewer ad clicks lead to less revenue. Getting new features out there that are snappy is the goal to keep the gravy train flowing.
The bias I have in favor of maintainability is something I kept in mind when evaluating React and Flux. We may have different goals, but I can completely understand where Facebook is coming from with React. The question you’re probably wondering is, “What about Flux?”
React vs Flux
Trying to maintain an application with that kind of complicated interaction matrix is a nightmare. The engineers at Facebook tried to rethink the entire MVC paradigm, and came up with something like this:
The flow of the application is unidirectional. The application moves from the action to the dispatcher to a store to a view, then recursively back to an action. Maintaining and debugging an application written in that fashion is infinitely easier than what was described above.
This is the most common motivation I’ve seen for why React and Flux were invented. After several hours of research, I came up with the following list (which lacks citations, sorry to my English 102 professor) of all the most common motivations I’ve seen for React and Flux:
- DOM writes are expensive.
- Independent widgets have unpredictable flows.
- In large applications written by developers of differing levels of ability, keeping the code consistent and maintainable is difficult.
These are concerns I’ve had with any application I’ve written. Although I don’t know it from end to end, I do not believe that React and Flux are a panacea for those concerns.
DOM writes are expensive
The graphic I’ve seen most used to illustrate this point comes from when Khan academy switched from Backbone to React. This graphic shows how React (bottom left) and Backbone (bottom right) behave when a computationally expensive operation (converting raw text to a fancy math equation) is performed:
Note that the Backbone version (bottom right) is choppy, whereas the React version (bottom left) is smooth. This is because React is only persisting the deltas on each keystroke to the DOM, but Backbone is rendering everything from scratch on a change.
I am in total agreement that trying to figure out how to do that efficiently in Backbone would be a challenge. I agree that in this situation I would use React for my view layer instead of Backbone. What I disagree with is that this means I should use React for every view everywhere. I have never worked on an application (nor have I heard of an application we’ve worked on at Keyhole) that has a piece that has a requirement for this kind of update. It seems an exception to the normal functionality we help our clients develop. Using React in places like this makes sense, but I can’t at this time see how this exception should make me completely rethink the rule of using Backbone.View as my standard view.
Independent widgets have unpredictable flows
Just as a reminder, this is the graphic I’ve seen that most commonly accompanies this concern:
If an application looks like this, I am in total agreement that its flow is going to be a major concern. No argument there.
The argument I have is that in an application like that flow is not the primary concern. That kind of application is simply not maintainable. Adding additional pieces has to be done either by an expert that knows every sharp edge of the troublesome application, or has to be done with duct tape and prayer. If your application looks like the diagram above, flow is the least of your worries.
A maintainable way to write an application is the following:
An action comes in, and is handled by one controller. The controller takes care of the orchestration of the event. The view is responsible for displaying HTML to the user. The model is responsible for being the mechanism by which communication with a server can be performed. The controller can delegate more specific aspects of functionality to subordinate controllers. Maintaining the supervisor/subordinate controller relationship bakes in the notion of application flow.
The dispatcher (supervisor controller) can talk to other dispatchers (subordinate controllers). The action data is stored in a store (model/collection). The action is eventually written to the view (view). This flow then repeats in exactly the same fashion as the MVC diagram above.
In large applications written by developers of differing levels of ability, keeping the code consistent and maintainable is difficult
Yes, I agree.
I created a GitHub repo for a React implementation of Grokola, our Q&A wiki platform. It was originally written in Backbone, so I wanted to see what a purely React implementation of it would look like. I learned more doing this than I ever having when using the typical To Do application approach to learning a new framework or library.
I’ll save my thoughts on how the coding went for my DevCon 5 presentation. So if you’ve liked it my blog so far, consider coming to see me yammer away for an hour.
— Zach Gardner, firstname.lastname@example.org