The problem with Angular

In the last six months or so I talked to several prospective clients that had a problem finding front-end consultants in order to help their dev teams get a grip on their Angular projects.

Although there are front-enders that are enthusiastic about Angular, I have the feeling that their number is surprisingly low for a major framework. I expected Angular to gain more traction than it has.

Angular is aimed at corporate IT departments rather than front-enders, many of whom are turned off by its peculiar coding style, its emulation of an HTML templating system that belongs on the server instead of in the browser, and its serious and fundamental performance issues.

I’d say Angular is mostly being used by people from a Java background because its coding style is aimed at them. Unfortunately they aren’t trained to recognise Angular’s performance problems.

I have doubts about Angular 1.x’s suitability for modern web development. If one is uncharitably inclined, one could describe it as a front-end framework by non-front-enders for non-front-enders.

The proposed radical Angular 2.0 rewrite aims to make it more palatable to front-enders, but I doubt they’re interested in yet another MVC framework. In addition, the rewrite will likely alienate Angular’s current target audience.

If you want to know why I think all of this I’m afraid you’re going to have to read this long article in its entirety.

Angular Server Pages

I feel that Angular’s fundamental proposition blurs the line between front end and back end. Take a look at this demo code example that I pulled straight from the horse’s mouth:

 <body>
    <h2>Todo</h2>
    <div ng-controller="TodoController">
      <span>{{remaining()}} of {{todos.length}} remaining</span>
      [ <a href="" ng-click="archive()">archive</a> ]
      <ul class="unstyled">
        <li ng-repeat="todo in todos">
          <input type="checkbox" ng-model="todo.done">
          <span class="done-{{todo.done}}">{{todo.text}}</span>
        </li>
      </ul>
      <form ng-submit="addTodo()">
        <input type="text" ng-model="todoText"  size="30"
               placeholder="add new todo here">
        <input class="btn-primary" type="submit" value="add">
      </form>
    </div>
  </body>

This code reminds me of a simple server-side scripting language such as JSP or ASP that’s used to fill HTML templates with database content. These languages have their place in the web development stack — but on the server, not in the browser.

Last month I gave a workshop at a large Dutch company. Their huge, sprawling website uses various widgets and design patterns that do the same job but aren’t derived from a common codebase but are copy-pasted throughout the site. This is clearly an undesirable situation.

They turned to Angular to solve this problem by including centralised widgets wherever they are needed. Although templating is the correct solution, doing it in the browser is fundamentally wrong. The cost of application maintenance should not be offloaded onto all their users’s browsers (we’re talking millions of hits per month here) — especially not the mobile ones. This job belongs on the server.

Strictly speaking this is not a problem with Angular, but with this particular company’s implementation of Angular. However, it’s logical that Angular, of all JavaScript frameworks, gives rise to this problem. Its JSP-like qualities are designed to allow, even encourage, such behaviour.

Angular’s target audience

Angular is aimed at large enterprise IT back-enders and managers who are confused by JavaScript’s insane proliferation of tools. In an excellent article, Andrew Austin makes the case for Angular in enterprise IT:

There are many positives about the AngularJS team all working for Google. For one, having one commercial entity control the framework can often be a positive because it completely avoids infighting between political factions. In the open source world, this infighting can be public and nasty, detracting for the team's purpose of building great software.

Enterprise IT managers want well-maintained code backed by a large company so that they don’t have to worry about a sudden lack of support. In addition, Google has a good name in web technology, so if they push a JavaScript library it must be good ... right?

Enterprise IT managers also like the fact that Angular closely mirrors the preferences of their back-end developers. I had an illuminating Twitter conversation with Joe Pearson of weather.com, who told me that they had recently switched to Angular, mostly for the sake of their Java developers. Angular used a type of code structuring that was well-suited to them, though not to their front-enders. From my clients I also got the impression that their Java developers decided to use Angular.

In other words, in addition to appealing to their managers, Angular appeals to Java developers. The framework ties in with their conceptions of proper application structure. None of this is an accident. Google aims to conquer the enterprise market, and Angular is one of its tools.

Many front-enders, on the other hand, who have worked with JavaScript and browsers for years and have developed their own coding style, tend to have their doubts about Angular.

In itself this is not a problem: people should just use whatever framework ties in with their coding style. Unfortunately Angular’s issues go much deeper.

Performance problems

Take another look at the Angular demo code:

 <body>
    <h2>Todo</h2>
    <div ng-controller="TodoController">
      <span>{{remaining()}} of {{todos.length}} remaining</span>
      [ <a href="" ng-click="archive()">archive</a> ]
      <ul class="unstyled">
        <li ng-repeat="todo in todos">
          <input type="checkbox" ng-model="todo.done">
          <span class="done-{{todo.done}}">{{todo.text}}</span>
        </li>
      </ul>
      <form ng-submit="addTodo()">
        <input type="text" ng-model="todoText"  size="30"
               placeholder="add new todo here">
        <input class="btn-primary" type="submit" value="add">
      </form>
    </div>
  </body>

All code snippets in {{}} are Angular instructions. The problem is that there is no way for Angular to discover these instructions except by parsing the entire DOM, including all text nodes and attribute values — a very expensive process if there ever was one, especially on mobile.

Although it is not necessarily lethal for overall performance, parsing the entire DOM at load time is an issue that should be addressed. Unfortunately this neglect of performance seems to be representative of Angular as a whole.

This test report by the Filament Group is not very flattering to Angular. Although the authors are extremely careful to note that test results for a large, complex app may be more positive, the Angular version of their simple test app did not perform well. Neither did the Ember one; only Backbone stood out.

Steven Czerwinksi provides interesting details:

Each update spent a lot of time creating and destroying DOM elements. If the new view has a different number of lines, or any line has a different number of words, Angular’s ng-repeat directive will create or destroy DOM elements accordingly. This turned out to be quite expensive.

Although the article shows how to address this problem fairly simply, what worries me is that this non-performant mode is Angular's default. Front-end framework defaults should use established front-end best practices. Angular’s don’t.

Even Google seems to agree there’s a problem. The Angular criticism that resonates most with me comes from the What’s wrong with Angular.js article by Daniel Steigerwald:

Google does not use Angular in production for their flag apps like Gmail or Gplus.

Ouch. Thou shalt eat thy own dogfood.

These problems are undetectable to an average back-ender with little front-end knowledge. The framework works as advertised, it comes from a company that has quite a reputation in front-end technology, so the average back-ender will understandably assume that this is how things ought to be done on the front end.

The Angular way

The biggest problem for many front-enders seems to be that Angular forces you to work in one specific way. The Software Improvement Group published a report that states (my emphasis):

Using AngularJS provides developers with a number of advantages. [...] These advantages have contributed to the increased popularity of AngularJS and lead to higher productivity when used within AngularJS’ constraints.

The report lists this issue as a pro, not as a con. In a self-admittedly opinionated rundown of JS frameworks, Henrik Joreteg is more negative:

Picking Angular means you’re learning Angular the framework instead of how to solve problems in JavaScript. [...] I’ve got developers who’s primary skill is Angular, not necessarily JavaScript.

Because of the need to learn the Angular way of doing things, the framework has a steep learning curve. Ben Nadel, who is an Angular fan, and not a detractor, visualises it here.

In other words, Angular requires you to spend a lot of time to teach yourself the Angular way of doing things. Some will like that, but others will see it as an extra investment and pass on the framework.

What went wrong?

Why all these problems? What’s wrong with Angular? Rob Eisenberg provides an explanation:

When AngularJS was first created, almost five years ago, it was not originally intended for developers. It was a tool targeted more at designers who needed to quickly build persistent HTML forms. Over time it has changed to accommodate a variety of scenarios and developers have picked it up and used it to build more and more complex applications.

See this Hacker News thread for more Angular history.

I don’t think that a rapid-prototyping framework should be used for complex, enterprise-level production code.

But there’s more. The same article gives another cause for concern:

While Angular can be used to build mobile apps, it wasn't designed with them in mind. This includes everything from the fundamental performance issues I've already mentioned to missing capabilities of its router, the inability to cache pre-compiled views and even lackluster touch support.

That a five-year-old framework is insufficiently mobile-optimised is understandable. Mobile simply wasn’t an issue back in 2010.

However, it’s not 2010 we should be looking at, but 2012. As far as I can remember, Google started pushing Angular in mid-2012. (That date is supported by this July 2012 article, which I think is one of the earliest to mention Angular.)

At that time, it was already clear that Android was going to be crucial for Google’s future, so it would make sense that the tool you push supports your future platform ... wouldn’t it?

I wonder what Google was thinking when it pushed a framework that wasn’t originally intended to assist developers, contained serious DOM performance problems, and wasn’t optimised to support its own mobile platform.

Right hand, meet left hand.

Angular and front end

Don’t get me wrong: there are front-enders who are enthusiastic about Angular. Module repositories and best practices sites exist.

My point is that I expected far more front-enders to embrace Angular. I have the feeling their number is surprisingly low — see also the problems my clients had with finding good front-end Angular consultants. Why is that the case?

Part of the answer is the possibility that Angular was designed to cater to the tastes of Java developers over JavaScript developers. That would turn off front-enders. Still, coding style is not language-exclusive, so this is not the whole answer.

A more important reason may be pushback from the JavaScript community. Angular has evoked some serious criticism. Alexey Migutsky summarises it best:

Angular.js is "good enough" for [the] majority of projects, but it is not good enough for professional web app development, [that is, an app] which is maintainable in [the] long run, performant in all reasonably modern browsers, has a smooth UX and is mobile-friendly.

I think he’s on to something. The long litany of complaints I summarised in this article, especially the performance issues, makes me doubt Angular 1.x’s suitability for modern front-end engineering. Angular either is a framework created by non-front-enders for non-front-enders, or it does an amazingly good job of hiding its front-end credentials.

That’s why I think Andrew Austin, who was quoted at the start of this article, is wrong when he states:

Compared to hiring jQuery developers, hiring AngularJS developers may be more difficult for an organization. [...] But don't worry, with each passing day more and more JavaScript developers are discovering AngularJS and they are using it to build real applications. [...] Rather than hiring developers with AngularJS experience, it may be easiest to train your existing team or hire JavaScript generalists interested in learning AngularJS.

For a front-ender, who’s used to doing things in a certain way, moving to the Angular way may be painful. In addition, they reject the performance issues that Angular causes. Angular insufficiently caters to frond-end sensibilities, so many front-enders tend to ignore it.

Back-enders do not have these problems. They have no preconceived notion of how front-end code is supposed to work, and aren’t trained to recognise Angular’s performance problems.

This is aggravated by a problem my Dutch client mentioned: in general, front-enders tend to dislike the enterprise because it’s perceived as boring — which is shorthand for corporate IT processes, endless meetings, taking weeks for solving simple problems, and so on. That thins the pool of available front-end Angular developers and consultants even more.

That’s why most Angular developers come from the back-end, particularly from Java. As far as I know this situation where a front-end framework is supported mostly by non-front-enders is unique.

Angular 2.0

The Angular team is not deaf to the complaints and concerns summarised here. In October it announced Angular 2.0, which would be a radical departure from 1.x. Angular users would have to re-code their sites in order to be able to deploy the new version.

It’s easy to understand why such a radical change is necessary. Giving Angular a serious performance boost requires ditching the {{}} DOM parsing at load time. In order to do so the syntax will have to change, and that will have serious consequences for the development process. I’d say Angular 2.0 will require developers to embed less application logic in their HTML templates, and more in their scripts.

I think that this radical rewrite is mostly aimed at front-enders, who will get much more performance and a coding style that is more in line with what we’ve come to expect of JavaScript frameworks.

However, this will come at the cost of alienating its biggest group of adopters. Enterprise IT opted for Angular exactly to be spared such sudden, critical changes. Adopting Angular 2.0 would require them to allocate massive amounts of budget to rewriting code that already works. Also, I wonder how people from a Java background will like new coding style.

For these reasons I think many enterprise users will stick with 1.x and ignore 2.0. Of course, Google will eventually stop supporting 1.x. Thus I think Google’s attempt at cracking the front-end enterprise nut with Angular is going to fail over the next two to three years.

While the enterprise IT defection could be offset by an influx of front-enders, Angular has meanwhile acquired a bad reputation among them. Besides, yet another MVC framework is not what the front-end world needs right now.

Despite its serious technical problems Angular 1.x is a success especially among corporate developers with a Java background. The 2.0 rewrite is aimed at front-end developers, but may not reach them, and in addition will turn off Angular’s current following. I don’t think Angular will survive the rewrite.

This is the blog of Peter-Paul Koch, web developer, consultant, and trainer. You can also follow him on Twitter or Mastodon.
Atom RSS

If you like this blog, why not donate a little bit of money to help me pay my bills?

Categories: