Re: AngularJS vs Ember
There's been an interesting article circulated on HN with a pretentious title
AngularJS vs Ember: It's not even close
According to its author, Ember won by a wide margin.
Why Care?
Several MV* frameworks are gaining traction these days. Angular, Ember and Knockout are arguably the most popular.
jQuery is way past its due date, and developers are ready to move on. What should we move to is an open question.
Angular works pretty well for me, but it is not perfect. It's great that people are trying to scrutinize its design, compare with alternatives and exchange general ideas. These things help the community progress forward. However, it's necessary to base discussion on real facts.
Sadly, the aforementioned article is not even close.
Simplicity: The Ultimate Sophistication
AngularJS is hard. It introduces many new hard to grasp concepts. It has many sharp edges, and it is not beginner friendly at all. Tutorials give you an impression that things are smooth and elegant, but you'll spend many days hitting walls in the dark, before your moves become as elegant as you saw in the Getting Started document. After about 6 months I still have a lot to explore.
Can you make judgements about Angular before you've mastered it? I think no, you hardly understand what you are talking about. While it doesn't have to be 6 months for everyone - I am a rather slow learner - you need to build at least one non-trivial thing.
If you think you can read a Getting Started doc, write a Hello World app, and make conclusions about Angular - either you are orders of magnitude smarter than me, or you've been mislead by an exaggerated promise on the Angular's landing page (more likely).
If you've read a couple of tutorials and blogs, talked to some Angular devs and decided you don't like it - chances are you just don't know enough.
We just got another example of that confusion happening to a seasoned developer.
You be the Judge
I wanted to present my arguments alongside the original statements, but that would make the post look like yet another flame war. Instead, I want to try something different.
Below, is the list of the arguments against AngularJS, as pointed by the author (rephrased for brevity). You can view my opinion on those, and decide for yourself who you agree with.
- Simplicity is the main reason why Angular has attracted more developers
It looks simple because it is well designed and decently explained. I was attracted to it because introductory examples are very cool. Other reason was that many smart people I follow online liked Angular.
- Ember has many hard to grasp concepts, which are not available in Angular, but absolutely needed in large "ambitious(tm)" apps
In its early days your Ember app will be more complicated than it has to be, you will be slowed down by unnecessary complexity. Later, your app will inevitably outgrow some aspect of the big monolithic framework, but you won't be able to fix or swap just that one piece. You'll have to either throw everything away or dig deep into the framework's guts.
- Ember developers put all extra stuff in for a reason (this reason is not explained, nor hints on where to look for an explanation are given)
Developers left stuff out of Angular for a reason. It's easy to create a bloated monolithic framework. It's much harder to make something useful, but small, focused and flexible at the same time.
- If you come from a server side MVC background, it's not clear what is AngularJS model?
If you are used to careful hand-holding by senior tutors, freedom will scare you.
- Any named data in Angular is model, not just objects and arrays, but primitives too
In the "classic" OO languages everything is an object, all the way down, until you reach turtles. But JavaScript uses prototype-based programming. It is hard to get used to it if you switch from Java, C++ or C#, takes some time. I know because I've been through it myself. Many great JS libraries don't use class hierarchies (except for CSS classes). You can call that idiomatic JavaScript if you want.
- In Ember you always have to extend Ember.Object, and that has a number of advantages
In Angular you are free to use Backbone or similar if it makes sense in your application.
- Author managed to name only one advantage of Ember.Object - computed properties on models
Angular supports computed properties in UI bindings. It's kind of a core feature, so it works really well. Do you need the same in your models? If it were a big deal - we'd see it elsewhere, there'd even be a trending library to do just that. Besides lack of demand, are computed properties really worth all the extra typing? Explicit declaration of all dependencies (hello maintainability)? Performance penalty? Will every assignment trigger a test of the (in most cases empty) list of dependants? If you have
Hotel
, how do you express dependency on an array element e.g. sum(hotel.rooms[i].beds)
?
- To render a computed property in Angular you have to write
{{ foo() }}
, to render a POJO property you write {{ foo }}
. In Ember it's always {{ foo }}
This sound like minor syntax sugar. We take this "problem" for granted in all programming languages. In JavaScript you can use getters, again, if you care. Yes, in worst case you have to update all references in all templates. In reality it's always a handful of places: first of all, computed property is defined in the controller, instead of the model class (controllers usually map one-to-one to a template). Secondly, if it's still dozen references - you most likely have serious issues with usability. Why else would same information be rendered in a dozen different places?
- In Ember you can chain getters safely.
Guess what! Angular templates also support this
{{ foo.bar.baz }}
will render an empty string if foo
or bar
is null. If you ever need safe getters in your model code (i.e. if you want to violate the
Law of Demeter) I'm sure there is already a 20 LOC library for that.
- Dirty checking means everything is recalculated all the time. If computation is non-trivial, or performed "hundreds or thousands of times" it would be very slow. (no real world example of a non-trivial computation is given, nor of rendering 100k expressions on a page)
Yes, that is a very big problem. In theory. But the last time I checked my mobile phone had 800 MHz dual-core CPU. Device is more than a year old, already obsolete model. Big boys like Facebook and Twitter don't use Angular but still bother implementing progressive loading of news feeds and images. So Angular is not the main reason why you'd want to keep your DOM small. Still, I agree that is a weak point of Angular. One need to constantly keep it in mind. In practice it's a tiny price to pay for all the power and productivity you gain.
- An undisclosed number of AngularJS developers said you need to cache function value if you have performance issues
Results of this 'poll' tell a lot, especially the omitted parts. Author talked to a number of Angular developers, but failed to extract a single real life example of performance problems. Nobody suggested a solution better than caching, extensions or patterns to improve dirty checking are not known to exist. Well, perhaps that means nobody really needed those yet.
$scope.$watch
belongs to scope and not to a model object. A blurry scenario is outlined where you'd have to iterate over an array of objects to watch a change of an element
Exactly because of $watch
being a scope method it usually watches a single element of an array. ng-repeat
, the awesome way to deal with lists, has multiple optimizations to reduce overhead. There are cases where you'd loop "constantly", this document is an example. But again, it's just a reiteration of the performance FUD.
- In an example when same model object "exists"(?) in multiple controllers, each controller will have its
$watch
and author speculates that it will be hard to debug and maintain
This is actually an example of Angular at its best - every template would just access a property of its controller. You wouldn't set up any watches manually, it would just work. If author used Angular for a real project, he'd know that this part does not need maintenance.
- In Ember you can pass a model object to a route's controller, but in Angular you'd pass an id only and would fetch the object from server each time (I may have misunderstood this part as I'm not very familiar with Ember and example is not explained in great detail, but I believe I interpreted it in a way most favorable to Ember)
This point actually sounds like something that Ember does better. Provided they got API and programming model right. Some part of Ember seems to be responsible for keeping a reference to the model object and passing it to the controller. In Angular services are responsible for fetching models, I don't see a reason why they couldn't do caching/memoization. Getting an object by id twice should return same instance anyway. Still, Ember probably gets a point here.
- Conclusion 1: it’s clear from above points that Angular’s focus on simplicity has some serious consequences. More stuff needs to be added to the framework, once you add it yourself in your project you'll end up with Ember
I'm not convinced I've been shown those serious consequences. Hopefully you clicked the thumbs up/down buttons. Is the screen mostly yellow or green for you?
- Conclusion 2: lack of conventions means many Angular developers rely on bad practices
Bad developers rely on bad practices, regardless of the framework they use. If Angular is only suitable for good developers (it may well be) it makes it even better.
- Conclusion 2a: lack of conventions means every member of the team will use different conventions and patterns.
This only happens in teams with poor communication and lack of code review. Again, regardless of the framework. Framework won't fix this problem, it will just make it harder to detect.
- Conclusion 3: it's not clear from blog posts and tutorials what is idiomatic AngularJS.
angularjs.org is full of "idiomatic" examples. You'll know your code is idiomatic when you write it.
- Conclusion 3a: it's not clear from blog posts how to reuse object instances
Maybe Ember has a special feature here. But think about all your projects - was it ever hard to load and reuse a model instance? I never needed help with that part. But updating UI state and all possible state transitions is always difficult. And this is what Angular is focused on.
- Conclusion 4: if you want to push boundaries of the web, add powerful features and maintain the app over time you must choose Ember
I think exact opposite is true - you need to be in control of your architecture, not outsource everything to a third party framework. Your requirements, market, and product will change over time - you need an option to alter some early choices over time.
- Conclusion 5: If you’re serious about front end development, I advise you to take the time to learn Ember properly
Absolutely. And I advise you to learn Angular properly. It will broaden your perspective.
- [I saved this bit for the end] Where does all this criticism come from? Straight from the horse's mouth:
I read through as much documentation, blog posts and guides as I could. I downloaded AngularJS and made simple applications.
Would you let a guy who have only built simple apps vet your technology choices? If I build some simple Ember apps, will Discourse hire me?
Conclusion
Lion's share of critical remarks are simply an attack on the philosophy of "bring your own" extension. I personally think narrowly focused tools are the way to go in software. Power and popularity of the Unix/Linux command line, slow death of XML and EJB, success of jQuery (a UI library that doesn't have modals or widgets), recent raise of Flask, etc. are great examples of modularity winning over monolithic tools. All-inclusive frameworks have their, often more prominent, place. But to declare them the only true way one should make a stronger case.
Ambition Is The Enemy of Agile
... and the enemy of Lean for that matter.
I once worked on a really ambitious web project. It was called Wave. Don't google it, you won't find its website. One thing I learned in that project and in many other during my career is that it is always a bad idea to add or build a generic framework before it is absolutely necessary. First I prefer to wait until I've violated DRY a couple of times, then wait some more until it starts to hurt. If lack of framework doesn't slow you down now, chances are your beautiful design just wastes everyone's time.
Votes Are In
Angular is OK | Undecided | Angular Sucks |
{{ count('A') }} | {{ count('U') }} | {{ count('E') }} |
Tweet me your results:
My score is @AngularJS {{ count('A') }} - {{ count('E') }} @EmberJS
Final Note
If you know Angular and I’ve written something wrong here, please contact me to let me know! I’d love to revisit or correct any mistakes or omissions.
Evil Trout
Sure! Let me know if you need more help.
Self-Promotion
If you liked this rant follow me on Twitter for more: