The dirty-checking loop is IMO a compromise they made because the ES6 standardisation body and consequently browser support for object observable is very, very slow - although it's been added in Chrome 35. I'm sure they'll rely on that full-time in Angular 2.0, maybe even as an option in a future 1.x Angualr release.
I agree on the module system, it's weird, causes naming clashes and I don't think it adds much since it's also not linked to a script loader of any kind.
As for the rest of your statement, I'm still going to say that application frameworks in Javascript are in its infancy; the single-page application paradigm is only ten years old (with Gmail being the first major one), and there have only been frameworks dedicated to SPA's in the past five years, with AngularJS only becoming popular in the past two (and solving a number of issues from its predecessors, like two-way binding, testability, etc).
Angular has its faults, but the alternatives aren't flawless either. Angular 2.0 will be the defining front-end framework for the next five years to come. It takes the lessons learned from Angular 1.x, Angular Dart, Durandal, and applies the bleeding edge in client-side scripting (ES 6). It's still got its weirdness (like square and round braces around HTML attributes, I have no clue what that's about), but I'm sure that none of the weirdness in that framework has been without thorough research and design discussions - I'd argue that it will be the most well-designed and well-thought-out front-end application framework in history, instead of a lot of current-day frameworks that sorta evolved into what they are today over the years.
Diff the virtual DOM to determine the minimal amount of imperative real DOM operations needed. Why is this so hard to understand as the optimal solution?
Heck, you can even re-render the entire DOM on every requestanimationframe. This is still better than AngularJS approach! Google Bloop for an example which is very easy to follow and can either support occlusion.
AngularJS is pure hype and ignorance.
To the best of my knowledge, React is indeed the first "mainstream" UI framework for JavaScript to be so fundamentally built around a virtual DOM. I think as a minimum the React team deserve credit for popularising the idea and for raising awareness of the underlying performance characteristics of browsers that make the idea relevant in practice.
That said, many of the "big ideas" that have been popularised among front-end web developers in recent years by big name frameworks are not even remotely new to the programming world as a whole.
For example, it's hardly news to anyone who's worked on browser-based UIs that DOM updates are often the bottleneck. However, back in the days of IE6/7 and the early versions of Mozilla or even Firefox and Chrome, JS generally and DOM updates in particular were far slower than they are in modern browsers. People have been writing UI code specifically to minimise DOM updates since long before the likes of Angular and React came along, because what is done today as a performance boost for relatively large and complicated pages used to be a necessity to get acceptable performance out of any JS-based UI at all (the major alternatives being either plugins like Flash or Java, which ran routine UI code much faster in those days, or doing pretty much all of the work server-side using old school web forms).
It's also hardly news to anyone who worked with client-server apps a few years ago, when again things were much slower and more specifically bandwidth was a fraction of what we enjoy today, that sending patches instead of complete data can be an easy performance win. (People have been using the rsync technique for a couple of decades or so.) In the early days of what we might now call web apps, before JSON won and everyone had numerous JSON-friendly persistence and data binding libraries to choose from, a comedian developed a format called XML that accidentally caught on when too many people didn't realise it was a joke. (See also: XMLHttpRequest, the standard tool for retrieving JSON data from servers everywhere.) In order to avoid half the development team retiring before the first test XML data had finished downloading on a typical project, we got pretty good at designing diff/patch formats for these kinds of nested data structures.
Put those two ideas together, and as you can imagine, a lot of web developers wrote a lot of ad-hoc tools whose basic purpose was to take some sort of change set for the underlying data model as input and figure out some sort of reasonably small set of DOM updates to match. The canonical example would be something like updating a container in your underlying data model, where you couldn't afford to rewrite a whole list or table element in your DOM for each inserted/changed/deleted element in the container, so you had to bundle up the changes transaction-style and then flag the DOM for a single update at the end.
Obviously we've learned a lot since the early versions of this, and today we enjoy templating and data binding libraries that can be dropped into projects with negligible effort but do the same jobs we used to spend many days automating on each new project, with all the usual benefits of consolidation and peer review that come from having generic libraries with many users and many contributors. No doubt some of the techniques used in modern frameworks like React are far more widely applicable and systematic than a lot of the old code we used to use. So in this sense, again, perhaps the React team deserve some credit for advancing the state of the art.
React gives you a powerful V that expresses things so intuitively that for most cases it eschews the help of a C or an M. That's a good thing when it's achievable.
I agree with a lot of what you say, but wonder if you're being rhetorical when you say Angular's popularity is baffling. Do you actually think that people pick tools by reviewing the CS literature and picking the one that best reflects the state of the art? :)
Angular is productive, people want to get things done; thus Angular is popular.
What is more precisely true is that the time taken by dirty checking per second scales with d×w×l, where d is the number of digest loops triggered per second, w is the number of watches, and l is the length of the digest cycle (the number of times that the watches are rerun before values stop changing).
Specific applications may find these variables to increase in different ways - all three will generally increase with application size, but for example, adding a digest on mousemove will immediately send d to a very high value.
What I really meant when I said O(N^2) was nothing precise though - just that, when I first read "every time you trigger a digest, we traverse every watch," it sounded like N^2 - it fit the pattern of "for every one of (growing number of things), do each one of (growing number of things)".
Digest on mousemove wouldn't be a good idea - look at _.throttle etc. You shouldn't realistically need digest loops more than once per 100ms, as people can't perceive changes happening faster.
It is kind of nuts that angular is big.
> writes a solution using jQuery
Angular tries to be clever and solve loads of problems, sure tables and table rendering sucks anyways, but a simple querySelector with jQuery is 98% slower than just using normal DOM methods.
If you're gonna write your own bits of code to improve the caveats of any framework, especially in the financial industry, you go full hog and you write it properly.
Fixing an angular problem with a jQuery solution will get you marginal gains. Fixing an angular problem with a DOM solution will get you the best results and it isn't even that hard.
A simple querySelector with jQuery maps directly to a normal DOM method in browsers that support it.
Yup. Because it's literally using javascript scoping/inheritance directly. A new $scope object from a parent $scope can be treated the same as the new scope inside of a function block because it's how prototypical inheritance works. Not surprising that they used the scoping system of the language they're building in.
> Now that angular is being widely used, people are noticing that it's slow...
With wide use comes wide misuse. This is not new either. A hammer makes a crappy screwdriver, but it works. If you don't know your tool, you're gonna have a bad time.
> people are finally realizing Angular has its faults
I hope you're right. Because the more that people think something is perfect, the more it disappoints them when they realize that nothing's perfect. Use the right tool for the job and know its strengths and weaknesses and you're less likely to get caught with your pants down.
This seems rather confused. There's lexical scoping with function blocks, and there's prototypical inheritance on objects, and yes in the abstract both are used for dereferencing identifiers. The parent post's point is that Angular's $scope rules are as though every function's scope behaves like prototypical inheritance on the call site rather than lexical name resolution. This is analogous to every function call being wrapped in a 'with' statement.
In a new lexical scope, a new variable of the same name as one accessed via closure means I lose reference enclosed variable. In the same way, a new property of the same name as a property in the prototype chain means I lose reference to that property somewhere up the chain.
I have a suspicion that it's all linked lists of hashmaps under the hood, though I haven't checked the source. At the very least, prototypical inheritance and lexical scoping can definitely both be implemented that way.
With dynamic scoping there are no guarantees about where you'll find any nonlocal variable. In practice this caused enough difficulty that the programming language community has moved steadily away from dynamic scoping.
You make an interesting parallel with prototype lookup, but it's worth noting that the prevailing pattern of prototype use mimics the traditional class and instance rubric. In that situation it is also fairly easy and deterministic to pin down where in the prototype chain every identifier is defined.
* with the exception of code which uses `with` statements and certain forms of eval, which is a big part of why those constructs are strongly discouraged by the community
Like others here, the app I was working on hit a hard performance limit with the digest cycle. When the main table of our app got to a certain number of rows it started to crawl on a desktop browser and was just unusable on a mobile device. And we tried so many things but there was just no real way out of it. It's crazy to me that people even offer up such things as infinite scrolling as a way out.
The weird thing was, I was by far the most experienced web developer working in that part of the organization, but all the backend/.NET dev and project managers were insisting on Angular as "the future of web development". I recall being spooked by how insistent they were, even though I had nothing against Angular at the time and wanted to learn it. Bringing up some performance caveat about data-binding wouldn't have gone anywhere, even had I the foresight to raise the issue.
I don't work there anymore but as far as I know they just... left it that way. So the most intensive users of the app got the worst experience. I know this is snarky but I suspect that's the kind of shop that should use Angular.
2) Angular was the first framework where you could take developers who didn't know JavaScript (or hated it for its worst parts / memories from the bad old days), but were used to learning frameworks (think Java people) and dealing with framework workarounds, and say, use this, you'll feel right at home.
Not really.
It is the remnants of a failed web startup. They offered a freemium backend as a service, but it didn't take off.
http://web.archive.org/web/20091230110525/http://getangular....
http://web.archive.org/web/20100215054417/http://www.angular...
Then I believe that one of the founders/authors was hired by google, and...
> They then attached "from Google" to the logo and it took off like a rocket.
Yeah.
In an interview last year one of the founders mentioned that angular was made for creating form based apps. That is its strong suit, which is fine, but it has been stretched so far now.
It's not the first time I hear that he doesn't mention BRAT Tech LLC when he tells the story behind Angular.
There is the adage that "good enough" is good enough, but there should be another one that starting really bad stays bad no matter how many fixes get applied year after year (then the magical 2.0 happens)
Look at good enough languages like Perl and Python, they have their faults, Python 3 solves a lot of them, but 2.7 stays in production because it really is good enough. People don't go bailing on it for some other option because their codebases got unmaintainable, performance problems got O(n^2) or worse, they just go bail because maybe they want to try the compiled ease of Go or maybe touch Julia over numpy here or there.
Bad is bad, and people need to use just a bit of their algorithms class to figure it out. Shame that a ton of people asking similar questions about "how do I _______" results in a higher PageRank, while time tested easy to use options just hide in the shadows of good documentation and infrequent code updates.
Angular's scope system is exactly analogous to the scope system of a programming language. This is a solved problem! When you make a scope system, make it lexical, and require explicit declaration before use. If you're not making those choices, then at least acknowledge that these are the standard answers, with very clear advantages over other scoping systems, and explain why you are not using these answers. But with angular, we have a dynamic, implicit declaration scoping system. New scopes are introduced somewhat unpredictably, at the discretion of each directive. I thought that introducing dynamic, implicit-declaration, non-block-scoped variables in 2014 was like introducing a new car with a coal-burning engine, but no one even seems to remark on it.
Then there's the dirty-checking loop. After every event there is a digest; every digest runs every watch. To me, just reading this description makes a voice speak up in my head: "Uh-oh! That sounds like O(n^2)!" Now that angular is being widely used, people are noticing that it's slow as shit. But why did the framework get to this level without anyone remarking, "this dirty-checking algorithm is fundamentally, irremediably not scalable"? Do people not have a sense even for the most coarse performance characteristics of algorithms like this? Or do people simply think that nowadays "performance does not matter"?
Angular's "module" system is the strangest of all. It doesn't do namespacing or dependency tracking. What is even the point of it? What thought process led to this useless module system?
It's just strange. Hundreds of years of people's work are spent on something, which the most cursory, CS 101 analysis shows to be seriously flawed. Is analysis simply a lost art in this industry?
Oh well, people are finally realizing Angular has its faults, because they've seen them with their own eyes and now they believe them. It would be nice if we could learn from this, and maybe skip the next boondoggle (web components for instance), but I have no hope for it.