
Faster AngularJS Rendering with ReactJS - adamnemecek
http://www.williambrownstreet.net/blog/2014/04/faster-angularjs-rendering-angularjs-and-reactjs/
======
lhorie
Meh. I'm fed up of spending hours trying to squeeze performance out of
Angular's directives system without breaking existing code, when there are so
many undocumented caveats, pitfalls, and subtle semantic differences between
this or that solution.

The issue of too many bindings he mentioned is a real one, and the complexity
of this solution in general shows what sort of hoops you end up having to go
through to get the _basic_ stuff working (i.e. a for loop).

This is part of the reason why I wrote Mithril (
[http://lhorie.github.io/mithril](http://lhorie.github.io/mithril) ) and the
main factor for why I am planning on replacing Angular altogether for our
mission critical app at work.

~~~
dustingetz
Some feedback: I clicked through to Mithril, saw "Virtual DOM diffing" and
thought, oh cool, immutable DOM is awesome (I use React). My next question
was, why would anyone choose this over React? I clicked around a little bit
but couldn't figure that out from the site.

~~~
lhorie
I put a performance comparison for React on the homepage yesterday (the link
takes you to the actual test page so you can run it yourself). It simply
measures running js time for initial rendering, which is the ugly, unavoidable
cost of frameworks that authors don't like to talk about. The numbers are
mostly averages, but should give a reasonable idea of what is faster than
what.

I also do go more in depth here (
[http://lhorie.github.io/mithril/comparison.html](http://lhorie.github.io/mithril/comparison.html)
). TL;DR: The main differences is that Mithril is a lightweight MVC, whereas
React is a powerhouse at doing only the "V" part.

There's actually a project that uses React to enable HTML-y Mithril templates
here ( [https://github.com/insin/msx](https://github.com/insin/msx) ), so the
two can certainly coexist.

Mithril's light weight is mostly a result of picking a very small set of tools
that are simple but useful on their own, but that also happen to come together
nicely and that can play ball w/ Javascript's FP capabilities and the JS
ecosystem as a whole.

Mithril is also a bit of a experiment in making a framework that gets out of
your way - more hacking and less figuring out what is the syntax to do X. If
that's your cup of tea, I'd recommend checking out the blog that I just
started last week ( [http://lhorie.github.io/mithril-
blog/](http://lhorie.github.io/mithril-blog/) ), where I talk about reusable
programming techniques.

------
mozey
I use jQuery to speed up specific Angular controllers with lots of binding.
The jQuery allows me to avoid the bindings on things like lists entirely. I
create a companion directive to my controller with isolate scope. The two then
communicate via events. Or the directive just calls the controllers functions
from the child scope. Inside the directive I can render the list using
something like Mustache, Handlebars, PureJS, etc. All of them seem to be
faster than Angular by a factor of 10. Using the jQuery I can then bind, for
example, one click handler to the entire list.

I load jQuery after Angular. This means Angular is still using jqLite - and
prevents the extra functionality from being abused in simpler use-cases.

Sometime in the future browsers will support Object.observe natively. At this
point I will scrap my companion directives and use Angular binding even in
long lists.

------
stephen123
I like to use Mustache.js for these cases. You don’t loose the templating, and
its damn faster. Looks like its faster than react to me.

[http://plnkr.co/edit/Slowpr?p=preview](http://plnkr.co/edit/Slowpr?p=preview)

I also talked about this here. [http://blog.stephenn.com/2014/03/javascript-
apps-and-renderi...](http://blog.stephenn.com/2014/03/javascript-apps-and-
rendering-big-lists.html)

------
Bahamut
I know this article only uses a simple example here, but it shows a hint of a
pattern that angular tries to keep away from the JS, the template generation -
generating the table children in the script sounds like a cumbersome pattern.

Otherwise, I think it's well known by heavy angular users that some of the
built-in angular directives are not necessarily the most efficient - building
custom versions of directives like ng-repeat has been the current solution to
squeeze out performance in edge cases, although it's unfortunate no one has
decided on open sourcing such yet.

One thing I am confident about is when Angular 2.0 hits, things should improve
immensely - the whole framework is moving towards modularity so you could
presumably swap out the template engine for React, or perhaps the revamp of
templating in Angular will make it more competitive performance-wise.

~~~
GamblersFallacy
You don't have to wait for Angular 2.0, the author of the article just didn't
know the "track by" feature of ng-repeat can be used to optimize performance
of rendering big arrays (and to be fair, the docs don't mention the trick
explicitly).

Here is the same demo, as in the article, with just 'track by $index" added to
ng-repeat. As you can see, to the human eye, its just as responsive as the
reactjs example.

[http://plnkr.co/edit/PHzYFa9N4RkxcDzZMcHk?p=preview](http://plnkr.co/edit/PHzYFa9N4RkxcDzZMcHk?p=preview)

~~~
jasim
The `track by` feature alone wouldn't solve Angular performance problems if
you are rendering a large dynamic table.

Every `ng-*` and text interpolation using `{{ }}` will add one binding per
usage. This can add up quite fast and easily cross the sweet spot of 2000
bindings per page ([http://stackoverflow.com/questions/9682092/databinding-in-
an...](http://stackoverflow.com/questions/9682092/databinding-in-angularjs)).

Large grids are not an ideal use case for Angular, and I like the approach of
using React/Mustache or even direct DOM manipulation inside an Angular
application when performance is critical.

~~~
GamblersFallacy
I've build a large custom dynamic table for a real-time datamining web app,
didn't have any performance issues because i used 'track by'.

The 2000 sweet spot comment from SO was based on angular 1.0.1, which didn't
have 'track by' & is approx 1/10 the speed of angular now.

Look @ the updated jsperf digest test, from the SO answer, for angular 1.0.1
vs 1.2.14 [http://jsperf.com/angularjs-digest/37](http://jsperf.com/angularjs-
digest/37)

------
jbeja
There is too much in the kitchen sink on this examples and the code look
inconsistent, the framework contradict themself one another and debuging
should be a pain in the neck. I don't like to put another layer of complexity
in my workflow, IMHO i would just pick one or the other.

------
JDDunn9
It looks like React will only really speed things up when you have over a
hundred items repeating. Seems like a pretty rare use-case scenario for the
additional 112KB overhead React brings with it.

~~~
littleiffel
ReactJs especially helps if there are more items to display (long list,
classic ng-repeat). But better rendering performance is not only on initial
DOM rendering but on every update of the data. So this greatly improves
usability for the user as the WebApp seems more reactive to input.

Mobile Webapps should provide feedback to the user as fast as possible on
input. With long lists that has been quite problematic so far, and I have been
looking for solutions to make the DOM update faster. ReactJs is a great help
here.

btw, I am the author of this article.

~~~
GamblersFallacy
With your native angular plnkr example, change ng-repeat to:

    
    
        ng-repeat="line in data track by $index"
    

Now try timing again.

[http://plnkr.co/edit/PHzYFa9N4RkxcDzZMcHk?p=preview](http://plnkr.co/edit/PHzYFa9N4RkxcDzZMcHk?p=preview)

~~~
littleiffel
I did try your example, and yes track by $index helps but only on updating the
DOm not initial rendering. Post got updated

~~~
GamblersFallacy
Interesting update. I never linked ng-repeat to the initial render lag with my
app (one page, 1200 - 3000 bindings), otherwise the performance is great.

I've assumed it was a server side issue I could tune before pushing to
production. Thanks, now I know where to look.

------
camus2
You dont need react for that.The fastest way is just to write a quick readonly
ng-repeat instead of mashing up both frameworks and ending up with something
unmaintainable.

------
wiradikusuma
Doesn't
[https://github.com/Pasvaz/bindonce](https://github.com/Pasvaz/bindonce)
already handle this?

~~~
mozey
No it doesn't - I haven't really seen any significant improvements when using
bindonce. An additional problem is that Angular is not fast generating the DOM
from template either. Never mind the performance hit of 2000+ bindings and
what it does to the responsiveness of the page. Just for generating the HTML
string from a template and appending it to the page I've found, for example,
Handlebars to be 10x faster than Angular.

