Hacker News new | comments | show | ask | jobs | submit login
Faster AngularJS Rendering with ReactJS (williambrownstreet.net)
81 points by adamnemecek on Apr 21, 2014 | hide | past | web | favorite | 29 comments

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 ) and the main factor for why I am planning on replacing Angular altogether for our mission critical app at work.

Mithril looks very interesting - added to my research list. I've skimmed through the docs and couldn't see the list of supported browsers - can you please advise?

Also, have you considered adding an entry to ToDoMVC project [1] for ease of comparison to other frameworks? I know it's not an exciting endeavour but it does make comparison much easier.

Thank you for creating it and your time in advance.

[1] https://github.com/tastejs/todomvc

You should be able to support all the way back to IE6 and Blackberry, although you need to include a few polyfills ( http://lhorie.github.io/mithril/tools.html )

Re: TodoMVC - there was someone working on an implementation here: https://github.com/jpmonette/todomvc-mithril

I think it's not fully implemented yet, but you should be able to see the general look and feel of the code.

If you are willing to consider a different direction entirely, I'm working on a little library for simple, declarative AJAX:


We do away with the client side model and complexity entirely and use partial HTML updates to get a better UX.

It isn't right for everything, but it is orders of magnitude simpler than Angular and it allows you to reuse many of the perf tuning tools we've developed over the last decade of web development.

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.

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 ). 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 ), 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/ ), where I talk about reusable programming techniques.

The "Performance" section of the linked page claims that Mithril takes 9.44ms where React takes 79.65ms for their rendering benchmark [1] [2]. If true, it could be a good enough reason to pick over React.

[1] http://lhorie.github.io/mithril/comparisons/mithril.renderin... [2] http://lhorie.github.io/mithril/comparisons/react.rendering....

Mithril looks very nice. I will look into that and see what happens in there. I understand your frustrations with AngularJs, I went through them as well, but still think that AngularJs is a great framework as BackboneJs and EmberJs and it has its strength and weaknesses.

Instead of contributing something to Angular's GH repo that would help your problems, or even creating a branch that's an angular-optimized branch, you create a whole new project. Why?

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.

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.


I also talked about this here. http://blog.stephenn.com/2014/03/javascript-apps-and-renderi...

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.

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.


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...).

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.

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

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.

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.

Hi, I'm Jordan a member of the React core team.

React is only 32kb(gzipped) in the production build (which also has performance optimizations that the development build does not).

We've also found that React helps make the rest of your application code much smaller, which may end up being even more important - but 32kb is certainly reasonable. We're extremely conscientious of page load speed and performance at Facebook which is why we place so much emphasis on React performance - second only to correctness and proper abstraction.

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.

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

    ng-repeat="line in data track by $index"
Now try timing again.


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

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.

If we are talking non-mobile and it takes 4 seconds off the rendering time, then I'm not sure why it's not worth 112KB? Especially since the 4 seconds are recurring costs per page and the 112KB are spread over the whole interaction.

Where are you seeing 4 seconds? The only benchmark is 1.3 seconds for 1500 rows (very large/rare) vs .3 seconds for React. I was saying that making all users download the additional file may not be worth it if only %.01 of your pages are going to see a noticeable benefit.

Quote from the article: "Rendering time dropped from about 4200ms in native AngularJs to 120ms using ReactJs." So just above 4 seconds. And yes, if you have an app where only one in 10000 pages need that sort of performance it might not be necessary. But it's a one time (per user) cost of 32KB download to improve the performance of the "challenging" parts of your app. Which can make a big difference in the perception of users. Especially since we didn't say anything about the distribution - if the 95% percentile is still 2+ seconds, the %.01 don't really matter.

I've seen serious performance problems with Angular for even reasonably sized lists (granted, with fairly complex display logic) that React handled without making the browser hang and then scrolling lag noticeably. So I'd personally rather drop the 36KB of Angular before dropping the 32KB of React. ;) But if someone is just displaying a handful of elements with simple logic and is happy with Angular's performance, then there's no need to frankenstein React into it.

heh yeah i don't really have performance benchmarks but i went React over Angular -- I've found the style to be a little odd (passing bound handler functions through descendants to update a state param in the grandparent class? surely they can prescribe something better) but the performance is perfect & the UI I'm working on is rather complex (a few hundred nested arrays of js objects that are themselves about 8 data points, with a lot of state-dependent display rules).

I feel like maybe Angular would be more convenient to program as an app, but I still have server-side logic -- my priority with a js lib is just to have a highly interactive UI even if it's just a fairly dumb state machine. To be honest, I feel like "dumb" has helped. I put just enough into state, just enough into events without being super model-oriented. Incidentally, I hear that is why Angular's perforance is poor (executes a bunch of js on model behavior even if it only results in 1 render -- not sure if this is true or not but I saw some interesting graphics of browser profiling that showed a ton of methods firing just for 1 small model update).

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.

Doesn't https://github.com/Pasvaz/bindonce already handle this?

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.

Guidelines | FAQ | Support | API | Security | Lists | Bookmarklet | Legal | Apply to YC | Contact