Hacker News new | past | comments | ask | show | jobs | submit login

I first tried to view this article on my mobile device and saw this: https://dl.dropboxusercontent.com/u/117695213/static/larseid...

To me, this is already revealing. A critique of a web framework and this is the first impression I get? Not off to a good start. There’s a reason people find it hard to trust a fat nutritionist. I see parallels here.

Lately there has been a lot of negative feedback about AngularJS and I have been interested in the critiques of its shortcomings. For this reason, I gave him the benefit of the doubt, pulled up the article on my computer, and dug in.

His initial complaint about prototypically inherited scope properties (Bad Idea #1) being confusing and "literally impossible" to predict was perplexing to me. He states that he understands a child scope will inherit from its parent scope, yet doesn't explicitly instantiate any object on the parent controller in his example of the so-called problem ( http://jsfiddle.net/1op3L9yo/ ). A child of a parent with no properties inherits nothing from its parent -- this seems obvious. If properties are actually defined on the parent the child will inherit them. Is this not the expected behavior?

The "fix" for his "impossible" scenario, is to make sure you explicitly define the property on the parent.

In his specific example, that would look like this:

$scope.obj = { prop: '' };

( http://jsfiddle.net/355fuxk5/ )

He complains: "Whether or not a new scope is introduced by a directive is up to its implementer. And if a new scope is introduced, it is up to its implementer to decide if it inherits from its parent scope or not."

How is this a bad idea? I like choices in life, don't you?

He talks about dynamic scoping being a terrible thing. I think the alternative, dictating One True Way of doing things, removes flexibility. This would be far worse than the current status quo of leaving it up to the developer. He advocates for removing this choice altogether, but is there NEVER a good use case for this "dynamic scoping"?

He also complains about the digest loop -- how two-way bindings constantly check for changes and impact performance as your number of bindings grow. There is truth to this, but it is easy to write your own directives that only update UI elements when a change occurs. This can easily be achieved in a variety of different ways. (The most universally familiar of which being a simple callback paradigm.)

Building a quality application with angular requires you to think, but I would argue that designing a performant application with ANY framework demands the same thing. You might initially think you get some things for free, but everything has its costs. If you want things to happen automagically, without needing to be explicit about the needs of your specific use case, that'll cost you. Is this not a near universal truth in programming? People fault the framework when, instead, they should be faulting themselves: their own laziness or lack of clarity.

He talks about having a page listing where their UI already had 2000 bindings and how clicking a "load more" button added another 1000 bindings, killing performance. I can't understand why you would possibly have that many bindings... for ANYTHING, unless you're Doing It Wrong. Why would you need any two-way bindings for explicitly appended information? When the user clicks "load more", we know something needs to change. If performance is a concern, why would you ever allow that listing to be automatically updated by checking for changes on every digest cycle? Instead, you can either explicitly update the element when the action is called (no two-way bindings), or use a SINGLE binding for the entire list. 1000 bindings? What could possibly be the justification for that?

Bindings can be drastically reduced and performance dramatically improved if you work to optimize your code and move from prototyping with built in ng-* components, to crafting components explicitly for your needs. I truly believe the standard ng-* components are meant more for prototyping and to serve as an example for how you can accomplish similar things as your write your own application specific code. Not being clear about this is perhaps one of angular's biggest failings.

Does it really surprise any programmer or developer that in order to achieve high performance in your application, you must architect explicitly for your use case?

To put it another way, in order to make a great application, you need to understand what is happening under the hood. If you're using components that you don't fully understand, that end up running a bunch of unnecessary operations, is that the framework's fault, or your own?

Is it really the role of the framework to do your development for you? You can either have things happen automagically, or have things be performant, but not both. This is reasonable and beyond logical, I think.

He critiques the language used in the documentation to explain controllers and hangs his hat on what he feels is the misuse of the word "constructor". His contention is that this is incorrect because the controller functions are being applied to an existing scope, not being instantiated in the traditional sense. Yet, and he even admits this, he is critiquing documentation that is over a year old. The current docs do a better job of clarifying what's actually happening. How is this a fair critique of a framework? Cherry picking year old documentation... this just seems silly, and as someone else said, disingenuous. Nothing is perfect, especially out of the gate, especially in open source -- I think we all know that.

His further complaints in this section employ the same strategy -- he takes segments from the documentation out of context and explains why they don't make sense. He even says that their use of the term "syntactic sugar" to describe the many options for creating components (services, factories, providers) is incorrect because, in his mind, "syntactic sugar" would imply a direct syntax modification to JavaScript or implementation of a custom language parser. Really?

Let's see what Wikipedia has to say on the subject:

"In computer science, syntactic sugar is syntax within a programming language that is designed to make things easier to read or to express. It makes the language "sweeter" for human use: things can be expressed more clearly, more concisely, or in an alternative style that some may prefer." (http://en.wikipedia.org/wiki/Syntactic_sugar)

Soooo, for example, angular's service and factory being abstractions over the provider implementation? When you don't need the full power of a provider using these higher level functions makes it more concise, easier to use, and "sweeter"... sounds like syntactic sugar to me, unless we're just being pedantic for the sake of it.

He says, "Angular seems to strive to make things as complicated as possible." I would argue that this simply isn't true, is shortsighted, and borderline insulting to the intelligence and efforts of angular's core team. I believe AngularJS is opinionated but it strives to make things as flexible as possible and as a result some inherent complexity exists.

In my (almost) 2 years of working with the framework, this is what I’ve found: AngularJS is extremely flexible. Its built in components are great for quick prototyping and its underlying structure provides an excellent FRAMEWORK for creating more purpose built, application specific, code. In my experience, angular is there when you want it to be and quickly gets out of your way when you don't need it. This is a robust framework. It is built for rapid prototyping and creating complex, performant applications (when properly executed). It is not baby's first framework.

How many times have we heard the old adage that, with most things in life, you get out what you put in. This is doubly true for angular (and development as a whole, I would speculate). If you're willing to put in the work, AngularJS can be a phenomenal tool in your arsenal. It can also be great for getting a prototype together, but one must understand, that a prototype is just that. Using ng-* components everywhere and expecting everything to work out optimally is just not going to happen. Did you REALLY think it would?

To pull a quote from his last paragraph:

"... many people like to recommend projects they haven’t used in any depth, because the idea of knowing what the next big thing is feels good. The result is that people choose frameworks largely based on advice from people who don’t know what they’re talking about."

The irony here is palpable. Change "recommend" to "criticize" and "knowing" to "condemning" and I almost needn't say more (he says, 8000 words later).




I've also been using angular for about the same amount of time, and I think a lot of what he's saying is valid. On more than one occasion, a co-worker would come asking for help with a bug and to explain why it was happening was far more complicated than it really should be.

Of course putting enough time on a framework can pay off once you've mastered the tool and know all the caveats. The problem is that if you weigh the pros vs the cons objectively, the cons are not something you can scoff at. Angular has a lot of complexity that is difficult to reason about, and there are a lot of traps along the way to mastery (speaking from experience seeing co-workers shoot their own feet).

For me, the biggest problem is that it throws some seriously useless errors (e.g. race-condition infdig on a route redirect). In a sane framework, errors are meant to direct you to the cause, not simply to announce that something somewhere is written in a way that the framework doesn't like because of complex reason foo. This can be a serious showstopper if you are more than a single developer working on the codebase and even more so if the rest of the team touching the codebase isn't made of Angular superstars (which is often the case).




Join us for AI Startup School this June 16-17 in San Francisco!

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

Search: