My own React vs. Angular
TL;DR
Today I am comparing the still new, pretty hype React + Flux front-end framework to the very popular Angular. I reach the conclusion that the Facebook one has a cleaner architecture, performs better and is easier to learn than its opponent. Hopefully I will make a point with the following, … at least to those who don’t have an opinion yet!
It’s all about the data babe
While coding a SPA, there are two new challenges that need to be addressed:
- How to keep the data up-to-date with the server
- How to maintain the data coherent within a page
Cut it short, I am not going to discuss the first one here. The reason is React and Angular pretty much deal with it the same way: they (barely) don’t, leaving the job to other libraries, like Restangular or Backbone, among others. Thus, discussing it here would be off-topic.
Let’s dive into the second challenge instead.
How to maintain the data coherent within a page during browsing?
Indeed, after the user has been browsing your app for half an hour without page reload, you can’t afford to display incoherent information like a log in button at the bottom while loggued in at the top and a different number of likes in the sub-menu than on the main page, right?
A practical example
Let’s take an example from an app I built with React: Novatu.be Like Button
What happens when the user clicks the button? 4 things:
- The
Like Button
goes into anactive
state, and changes its text from ‘Like’ to ‘Liked’ - The
Like Counter
of the current track is updated from 0 to 1 - In the tracklist, the
Like Counter
of the track is updated from 0 to 1 - In the tracklist, the playing track goes into a
liked
state, adding an heart on it jacket
Here is screenshot after the user clicked the button:
Now, let’s discuss the different possibilities we have to handle those changes.
100% hand-coded: jQuery
Using jQuery, coding this behavior can quickly become a mess. Let’s give it a try:
With the initial HTML:
We would have to write the following JS:
Not only is it complicated and hard to read/maintain but it is not DRY: the ‘Like’ content is repeated in the HTML and in the JS. In addition, there is no guaranty that the data is synchronised with the server. There is no way to prevent another JS script to add the active
class to the .btn-like
button.
That said, this code only tackles one like button. Imagine if we were to handle comments, replies, etc.
That’s when frameworks come to the rescue.
The component architecture
Angular and React, like most front-end frameworks, tackle this issue by creating isolated components. Instead of having to control a full web page with a wide DOM, we’d rather manipulate smaller boxes with limited input and output, right?
That’s a component. Think of a function that has a few parameters input, and has the capacity to output, well, the HTML that will be displayed on the page.
Back to our former example, we could isolate different parts of our app like so:
1. Like Counter
Hence the Like Counter
can render by simply having the nbLikes
parameter:
2. Like Button
The Like Button
is a little trickier: it needs the isLiked
parameter, but also to know what to do onClick
:
3. Current Track
Since it is possible to compose components together, the Current Track
component would describe as so:
You got it, right?
In a schema, the whole decomposition would be:
This component-oriented architecture is common to Angular and React.
So what’s the difference between the two frameworks? Answer:
The difference lies in how the data flows among the components.
The Angular double data-binding
Angular is famous for having the double way data-binding. If it is changed in a component, it will tell the other connected components. On a schema, here are the different channels of communication for the data:
Here’s how things go when the user clicks the Like Button:
- If the
LIKEBUTTON
component is clicked, it is the component itself that is in charge of talking to the server, and receiving the result:{isLiked: true, nbLikes: 1}
- Once received, the
LIKEBUTTON
will tellCURRENTTRACK
about the change. CURRENTTRACK
will dispatch toLIKECOUNTER
and theBRAIN
- The
BRAIN
will tell theTRACKLIST
- The
TRACKLIST
will inform the concernedTRACK
- The
TRACK
will inform theCOUNTER
- It is only when every component received the value that the component are re-rendered and the UI is updated.
On a schema:
The React + Flux architecture:
This time, we have a different architecture based on something you may have heard of along with React: Flux. The idea of Flux is that the whole business logic and data should lie in the Brain, then the components only access the data in a read-only mode.
So here’s what happens when the user clicks the like button:
- When the button is clicked, it has been wired to call a method in the
BRAIN
, calledlikeButtonClicked
- This method is in charge of making the API call to the server, and updating the
BRAIN
accordingly. - The
BRAIN
tells its children component that he has new value CURRENTTRACK
andTRACKLIST
tell their children components that they have new value- The
TRACK
which corresponds to theCURRENTTRACK
knows it has changed values and tells itsCOUNTER
to update - Those modifications are reported to the UI which is updated if it is ready to do so
On a schema:
Conclusions
Angular’s very advertised double-way data-binding has a great advantage : things are binded together automagically. Less questions to ask oneself, less behavior to describe: everything’s plug and play.
But this abstraction comes at a cost:
- React has a better architecture
- React has better performances
- Angular is harder to learn
1. React has a better architecture
Having components to read-only the data from a single source dramatically reduces risks of incoherence, which is what we were trying to achieve a first, remember?
Besides, I find it easier to have all the business logic and data in the same place. If someone needs to use this code, he will definitely find it. In Angular you’d have quickly duplicated methods that do component specific behavior, like the API call on button click.
2. React has better performances
When Angular recalculates the values in every component, it is called a $digest
cycle. Since we have double-way data binding, it is very often that the following occurs:
If those calculation are expensive - and they eventually will be - recalculating the same things even 2 times is a waste. With React, we have full control on when the components should be updated so we can be 100% sure it will only occur when necessary. And since the parameters are read-only, there are no chances that a children component parameter influences its parent one.
There is another situation where React performs better than Angular. If the $digest
cycle is super fast in Angular, then the DOM will be updated accordingly. But updating the DOM is a relatively expensive operation too. So it can occur that the browser is still rendering something that is already obsolete in the Angular world. With React, the smart Facebook guys created a virtual DOM which is fast to update, and which reports its modifications to the actual DOM on a frequency adapted to what the browser can hold. If a state was too short living to be rendered in the DOM, it never will.
3. Angular is harder to learn
Eventually, while Angular’s learning curve is famous for being steep, I found React very quickly accessible. If you are curious, read the getting started tutorial, and you will definitely be good to go within few hours, especially after having read this! :-D
Read Further
How to display comments on a web page
Comments replies are too often not correctly hierarchised
Continue →10 tips on how to improve design skills as a web developer
Developers often have a thing against design
Continue →