Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

People claiming that framework size doesn't matter is a bit of a pet peeve for me: download size may not matter once the files are cached, but the uncompressed size still translates directly to how much code the browser needs to parse and execute on every page load, and may also negatively affect the weight of execution payloads across operations in your app.

These costs are not as small as you might expect. The performance tests I put on the Mithril ( http://lhorie.github.io/mithril ) site illustrate this problem. I don't have Ember there, but if anyone more familiar with it would like to contribute (the rendering test is really simple), that would be most welcome.

There's another independent test here ( http://jsperf.com/angular-vs-knockout-vs-ember/292 ), which actually surprised me.



In general:

    how much code the browser needs to parse and execute on every page load
The caveat being that that code only needs to be parsed and executed once in a single page application.

    weight of execution payloads across operations in your app
Presumably this cost is providing value to the developer in terms of reduced development time, reduced complexity, or improved correctness. You shouldn't typically incur significant wasted cost in execution, just a selection of tradeoff. Besides, rendering to DOM is still the longest tentpole by far compared to microseconds for JS execution.

EDIT: With regards to the "independent test," that is in no way a realistic use case. You would never add items to the DOM individually when you're in that tight of a loop. You would instead build up a cache and write once. The only thing of consequence that is being measured in that benchmark is each framework's DOM insertion speed.


>> The caveat being that that code only needs to be parsed and executed once in a single page application.

Sure, if you don't consider users that open lots of tabs, or users that close their browsers periodically (e.g. mobile).

>> Presumably this cost is providing value to the developer in terms of reduced development time, reduced complexity, or improved correctness. You shouldn't typically incur significant wasted cost in execution

Ideally that would be the case, but from my Angular experience, it's unfortunately not always so clear cut (e.g. filter caching is a good example of time wasted in refactoring for performance reasons)

>> You would never add items to the DOM individually

I was under the impression that this is more or less what everyone was criticizing about Backbone rendering a few months ago when that Om article came out.


I think its important to note with the perf test and download size stuff that the frameworks that are bigger/slower to render provide more functionality and more templating options respectively. Thats not to say they're better, but just trying to clarify the tradeoffs under discussion.


That's not necessarily true. I can't speak for the jsperf test since it's not mine, but for the Mithril site tests, I exclude "optional-but-not-really" things like Marionette and ngRoute/ngResource/friends from the tests (whereas I include the entirety of Mithril - templating engine, router, etc) to try and tilt the tests in other frameworks' favor.

Sure one could argue that Angular has filters or whatever, but hey with Mithril you can express templating things that you can't with Angular (e.g. tables with nested loops, or w/ for-else constructs), so it's not really a apples to apple trucks comparison. With an order of magnitude more code, one has to wonder how much of that extra code is more functionality and how much is just bloat.


A big factor here is that Mithril describes templates programmatically rather than strings of data. It's the difference between:

  function render() { eval("(function () {}());"); }
and

  function render() { (function () {}()); }
These are going to run at much different speeds because one involves parsing multiple times while the other only needs to be parsed once. The tradeoff is some complexity (though there's also more flexibility too).

  <ul class="foo">  
    <li data-ng-repeat="item in items">
      {{item.x}}
    </li>  
  </ul>

  m("ul.foo", [  
    items.map(function (item) { 
      m("li", item.x);  
    });  
  ]);


Yep. I'd argue that Angular is far more complex though, with its `track by $index` and `ng-repeat-start`/`ng-repeat-end` and the scoping implications of caching filtered expressions in the view and the `ng-init` watcher trap and all that. But I digress.


> With an order of magnitude more code, one has to wonder how much of that extra code is more functionality and how much is just bloat.

Sorry but that is almost the archetypal FUD sentence of the 'micro framework'. And the more you analyse the 'lots of code must = bloat' sentiment, the more ludicrous it becomes.

Look at the docs. If you see functionality in Angular that you think is unnecessary then file an issue, or write a blog post explaining the alternative approach. Please don't spread lazy FUD like this, it helps nobody.


I did write a little bit about this in the comparisons page on the Mithril site ( http://lhorie.github.io/mithril/comparison.html ) and I am actually writing an article about this topic (specifically, about lessons I learned from using Angular that apply to Mithril) that I'm planning on publishing this weekend over at the blog ( http://lhorie.github.io/mithril-blog ). There's a feed you can subscribe to if you're interested.

There's also a reasonable amount of docs on the main site about the approaches that I do propose for various aspects of the MVC stack (e.g. see templating, components, etc).

I'm not saying more code is always necessarily bloat, but the correlation between code size and bloatedness does exist, whether you like it or not. I think what is ludicrous is to assume that all of the organically grown code over the years is somehow made up of only useful harmonious features.

Off the top of my head, I could immediately think of angular's directive system, and $scope as things that are probably far more complex than they should be, but these aren't exactly things you can "file an issue" for. So I did the next best thing and scratched my own itch.


Sure. Size is a con, functionality is a pro. The point is to correctly weight each. I don't really have strong opinion on what "correct" is, in the general case - I could formulate opinions confronted with specifics.


Your jsperf test is not measuring the same thing as the other frameworks.

You need to insert m.redraw() in the loop to make the comparison apples-to-apples. My test shows it is as 3x faster, not 100x which is completely implausible.


It's not my test, but m.endComputation() - which is in the loop - does call m.redraw() internally.

With that being said, if there's something there that is wrong that I'm not seeing, I'd be happy to hear it, as I am skeptical about the number as well.


No it doesn't. It calls redraw(), not m.redraw().

redraw() is debounced. m.redraw() is not. The test doesn't redraw every loop, it redraws every 16ms.

You need to call m.redraw() in the loop to get an apples to apple comparison.

Edit: Also your post redraw hook looks really buggy. It can run before the redraw actually happens.


Yeah sorry, you're right. Just as I went out for lunch, it occurred to me that I was looking at a bleeding edge version (which has a refactor of this code) and not the version being used in the test.

I had a feeling there was something fishy about the number but I couldn't quite put my finger on it. Thanks! :)

PS: and thanks for catching that post redraw hook issue; I'll add a fix for it.




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

Search: