In the front-end framework race there are many contenders, but the one that stands out from most is AngularJS which is supported by Google. It simplifies the process of complicated and simple application flow, but when it comes to rendering many items (especially using ng-repeat) you soon notice AngularJS struggles.
I will not bother posting my own benchmarks, as there is pretty conclusive proof out there you can find via a Google search. I love Angular, do not get me wrong, but it sucks for rendering lots of UI items, like for example a large catalogue of products comprised of; titles, descriptions, star ratings and a thumbnail image.
All preexisting solutions out there to combat the issue of many items and bad performance in an AngularJS application are merely hacks to get around what is a shortcoming of the framework itself. You could argue one-way binding, but you lose the ability to have dynamic items, pagination and more, but each solution has its tradeoffs which for some, might be too much of a tradeoff to implement.
This is where ReactJS comes into the fray. While AngularJS aims to be MVC (Module View Controller) ReactJS likes to call itself the “V” in MVC. This means you can use ReactJS in the form of an AngularJS directive to render items and keep track of their state.
The issue with AngularJS is that it works on the premise of directly watching and modifying the DOM (using dirty checking). In the instance of a large amount of “ng-repeat” items, if you have watchers on potentially thousands of elements in the page, it does not take a computer scientist to work out what will happen: performance will suffer.
The premise of ReactJS is something it calls a virtual DOM. This is an in-memory representation of your DOM, when a change is made, it is made in memory and the DOM is subsequently updated when needed.
Rather than checking the DOM for what has changed and what needs to be updated, all of this is handled in memory which results in blazingly fast mass updates and changes to the DOM because the heavy work is being off-lifted outside of the page itself.
I like to think of ReactJS as a NoSQL database for the DOM. While the underlying codebase of ReactJS is anything but simple, the premise of ReactJS is simple enough to know it is effectively a key/value store for the DOM (only you’re not querying elements, but rather the way it keeps the DOM structure in memory and checks what has changed). It is incredibly easy to learn and pick up, the learning curve is a whole lot more simpler than AngularJS is to learn.
Controversy…
Now some people would argue that you should not mix the two and in an ideal world, that is probably a good recommendation. However, recently whilst working on a large-scale project in AngularJS, the use of ReactJS was warranted because it was better than the alternative of poor browser performance and a bad user experience.
The beautiful thing about ReactJS is that it does not care what front-end framework you are using. All it cares about is rendering HTML markup that has been Reactified and created within the React component itself. This allows you to use the features in AngularJS like services and factories and effectively replace “ng-repeat” with ReactJS instead.
If I were to start a new project tomorrow, I would definitely just use ReactJS in combination with Flux to build my application without AngularJS (as far as I could feasibly do so). You could effectively build a Facebook like web application using Node.js as the server and ReactJS as the front-end.
However, the reality is, not all of us developers have the luxury of being able to throw existing code away and start again from scratch, especially in a large organisation, it just does not make any sense. But if you are stuck trying to optimise a preexisting application in AngularJS this is a good solution that gives you the view rendering power of ReactJS and the versatility of AngularJS.
Angular: The lovable quirky beast
While I am a big fan of Angular, it does have some performance issues and various quirks. If you know what they are and how to work around them, Angular can be performant and great. The biggest issue is two-way binding which basically allows a value to be tracked and update via a $digest.cycle() called every time something happens.
Because ECMAScript 5 does not support watching values out of the box like ES7 and object.observe()
Angular implements its own checking mechanism which can cause you a lot of headaches, especially if dealing with a lot of elements in a page. This is not an issue only specific to Angular, all front-end frameworks have this issue, until ES6 is a thing evergreen browsers support anyway.
In instances where you are plotting lots of elements into a page and wanting to interact with them, change their values (perhaps a graph for example) you are going to find Angular has a glass ceiling and when you break it, you run into performance issues that require serious refactoring (and in some cases, issues that cannot be resolved at all).
How do I use the two together?
You can roll your own custom directive functionality or you can use a robust existing solution like ngReact to implement the power of ReactJS into AngularJS.
While I have experience using both approaches, to save time, I would use ngReact and not worry about rolling your own solution unless you need additional power this library addon cannot already provide you.
An important note
Please also note that while AngularJS and ReactJS can be used together, the recommended approach is to use one or another, in an ideal world. ReactJS is not as opinionated as AngularJS and I would argue is not really a front-end framework at all. So the two cannot be compared, but one or the other or both can be used.
Inform your yourself and form your own opinions. As always, not all tools can or should be used for everything. Use what works for you and forget the rest.
Enjoy.
Nice Article.
Yeah, nice and interesting. Thanks for the comparison.
Nice Post !!
thanks for the clarification made. Its really been of help
Best insight into the on-going matter – thanks 🙂
Interested in seeing a bit of benchmarking from your personal experience showing the increase in performance when you switched to handling your “view” with React components.
I’m always interested in knowing what these large ng-repeat views are where the users are going to be modifying elements.
Got a link?
Cheers,
Oleg
Oleg,
Sorry the benchmarking work was performed on a job I was previously contracting on (when I published this) and as such I don’t have anything from that job. The rendering time was night and day though. We were seeing rendering times in the seconds, increasingly worse as more items were displayed. When we used React, it dropped to a more acceptable 280ms (initial load) for about 1200 items.
Since then Angular 1.x has also changed. The one-time bindings they introduced allow you to address some of the issues with data-binding inside of a ngRpeat. It still won’t fix everything, but using them can definitely reduce some overhead (especially when dealing with large items).
Also worth pointing out during our benchmarking, we knew we would be dealing with potentially 1000+ items being displayed. We tried various things like slicing up arrays and whatnot, but ngRepeat isn’t a flexible iterator, so we ended up with just one array we pushed items into.
We even tried clever solutions like taking the scroll distance and determining if we could trim items off of the top of the array when the user scrolls down and put them back when they scroll up, trimming items off the end instead. It caused jumping issues and other weird artefacts, so we stuck with ngRepeat and React.js.
In the end we realised that Angular 1.x had some issues that could not be resolved (at least not for initial render) and React.js became essentially. We could have also cut out the infinite loading and used pagination to limit items per page, but the product team didn’t want that.
Good Article. I personally don’t prefer either React JS or Angular JS — they are both good in their own ways, but have limitations. React JS is faster, but the code can easily get messy as the code related to rendering is mixed with other application logic. It looks like PHP whereas we wanted to move forward with MVC model thereby demarcating view from model. Angular is good but gets complicated with complex UIs having many UI items or controls. I like Meteor.js, but there is a talk on Blaze getting decommissioned, in which case we need to look for more stable client side Javascript frameworks.