Note

This blog post will cover Facebook’s React JavaScript library and Flux application architecture paradigm. It is a summary of the presentation I presented at DevCon 5 on 7/22/2015 in NYC.

Introduction

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.

Context

A lot of the JavaScript applications we help write here at Keyhole are for large companies with very big teams responsible for developing a product. They range from financial institutions to health care companies, so they tend to have very specific goals in mind for the applications we help them write. That lens is what I often look through when judging new libraries or frameworks.

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

Up to this point I haven’t really defined what React and Flux actually are. In as simple terms as I can come up with, Flux is an application architecture paradigm that recommends a unidirectional application flow, and React is the JavaScript implementation of Flux.

These two were born out of Facebook’s attempt to use traditional MVC to develop their JavaScript web application. The MVC diagram that is most commonly used to describe its origin is the following:



From InfoQ

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:



From InfoQ

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

I’ve seen this concern come up when developers talk about pieces of JavaScript that cause a large number of reflows and repaints. Rather than allowing a component to interact with the DOM at any time it wants, React’s Virtual DOM ensures that updates to the DOM are kept to a minimum. The Virtual DOM helps mitigate any mistakes a developer may make by only writing deltas to the DOM when a change occurs.

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:



From InfoQ

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.

This is the pattern that is used in almost every server-side language I know of. Every maintainable JavaScript application I know of uses some derivation of this pattern. Interestingly enough, Flux is pretty close to this pattern as well. This is the graphic I showed above:



From InfoQ

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.

On this point I agree in principle with Facebook’s Flux team. I disagree, however, that it takes a completely new library to achieve this pattern. All you have to do to achieve the MVC pattern I showed above in Backbone is to create a Backbone.Controller class, let it know about other Backbone.Controllers, give it a member variable for view, and presto-chango you have the start of a maintainable JavaScript MVC application.

In large applications written by developers of differing levels of ability, keeping the code consistent and maintainable is difficult

Yes, I agree.

Seriously, yes.

I mean it, I actually agree. If I were the lead architect for a large JavaScript project with developers of differing skill levels, I would seriously consider using React.

Thankfully I’m not. 🙂 Most of the projects I’ve consulted on had very small front end teams with above-average JavaScript skills. The more successful of those chose libraries and frameworks that allowed the skills of the team to shine without being hampered by constraints or patterns not of their choosing. I enjoy JavaScript because I know its strengths and pitfalls, and I make a conscious effort to avoid those pitfalls. Having the freedom to make stupid mistakes and choosing not to make them is better for me than limiting the amazing things I can do at the cost of never being able to make a mistake.

If I had a small team of JavaScript developers that were really strong with the language, I feel something like React would hamper rather than strengthen the team. Backbone in that case would be a better choice so the team could developer their own patterns and play it to their strengths. I can, however, see how a large team may benefit from the uniformity that React provides. The same thing could be said of any other JavaScript framework, so this is still an area that React is not the de facto standard.

Code Introduction

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.

Conclusion

Facebook’s React/Flux is an interesting take on the MVC paradigm in JavaScript. While I disagree with the results, I understand where Facebook is coming from with these two pieces of the front end puzzle. I still think that an MVC Backbone application is what I would choose for a small team of strong JavaScript developers.

But if I had to give a recommendation for a large team with varying levels of JavaScript skill, then React would be something I would consider.

— Zach Gardner, [email protected]

[thumbs-rating-buttons]