Angular 11
blog.angular.io
blog.angular.io
Every ngconf there's talk of the magical 2kb hello-world and bundle improvements with every major, yet the only bundles getting reductions are the hello-worlds and monster projects.
It seems we're in the medium bundle category and it's just disappointing that every version our bundle size hasn't moved or increased slightly.
We're currently at 2mb main/vendor after spending A LOT of time optimising and making everything lazy and then a team of 1 at our sister company release a Next.JS/React app with a main bundle about 1.3mb than ours using zero effort.
There's never anything obvious when it comes to analysing the bundle and it seems we're using everything we need: Angular, Material, RxJS, ApolloClient. Most of our forms use Formly (huge savings from repeated HTML)
All of our competitors are running React and have bundles about 1mb smaller than ours.
Every year I install the VSC Language Service plugin and have to disable it the same day due to it continuously crashing and killing the editor so it seems we'll never get to benefit from that.
Then I see a continuous stream of core developers leaving the Angular project due to toxic behaviour from Igor and it feels hopeless and depressing.
The one saving grace is that the entire ecosystem is written in TypeScript and it's nice seeing everything typed to perfection.
>our bundle size hasn't moved or increased slightly
Please make sure you are using the latest version of our compiler and runtime. Many developers observed significant improvements after the v9 release. Here's just one [example](https://news.ycombinator.com/item?id=22260864).
>Every ngconf there's talk of the magical 2kb hello-world
Currently, it's absolutely doable to get very small bundle size (<7-8KB) for a hello-world application. This, however, relies on private APIs. We haven't made them public yet, because not many folks are building hello world apps, but in the future we'll be exploring how to reduce the footprints of the framework even further for smaller apps.
>We're currently at 2mb main/vendor after spending A LOT of time optimising and making everything lazy
It is shocking for me that you're spending that much effort on optimizing your app, but you can't get your bundle below 2MB. I'm spending large chunk of my time looking into apps and thinking how to make them smaller & faster. I'll be more than happy to connect and brainstorm the same for your case. Please reach out to me on my hackernews username @google.com
>Every year I install the VSC Language Service plugin and have to disable it the same day due to it continuously crashing and killing the editor so it seems we'll never get to benefit from that.
Sorry to hear you had such an experience with the language service. If it keeps crashing, definitely report the problem here https://github.com/angular/angular/issues. We'll be very thankful if you share reproduction steps.
>Then I see a continuous stream of core developers leaving the Angular project due to toxic behaviour from Igor and it feels hopeless and depressing.
Folks leave and and others join. I can't comment on my co-workers experiences, but after 2 years working on Angular I haven't experienced any of the behavior you're referring to.
>The one saving grace is that the entire ecosystem is written in TypeScript and it's nice seeing everything typed to perfection.
Oh, I wish everything was that perfectly typed :). This is something the team and the community is constantly working on, but we still have a long way to go until we reach perfection.
If I had to say two things that I would like to get improved: 1) better typing related to Reactive Forms and Angular Material (e.g. IIRC Material dynamic table definitions were declared in a way that it lost IDE navigation and static analysis) 2) Faster compiling times, but we got this to be good enough for hot-reloading which matters most.
RxJS Observables with Push ChangeDetection was heavily used.
Personally just thanks for your contribution to make web developing more enjoyable!
Our site is entirely data-driven via CMS and each of the Material components are available for use from there, which is why they're all in use.
We're using the latest of everything (v10 atm) as we're using Renovate so it's all correct etc
Don't get me wrong, I like those bundles - and I like my frameworks over engineered. They take care of edge cases. And if I'd write a CMS I'd be all over those packages. But if your constraint is bundle size, you have to avoid them.
There are tools that produce smaller bundle size (e.g. stencil and react) but angular has much better DX.
Svelte maybe better but not used it in production yet.
https://medium.com/@jeffbcross/jeffs-letter-to-the-angular-t...
It's not easy to share such a personal story publicly. I'm sorry he had such experience and I'm not saying he does not have the right to be upset. He knows the best what he went through and how he feels.
I'm just saying that it's not correct to generalize and gave myself as an example for someone who can't relate to his experience.
The only thing I'm saying is that it is not correct to generalize, giving myself as an example for someone who haven't experienced anything similar.
I've no idea how you reached that conclusion given that the comment you're replying to says
>> I'm sorry he had such experience and I'm not saying he does not have the right to be upset. He knows the best what he went through and how he feels.
Indeed he goes on to make this clear: “The only thing I'm saying is that it is not correct to generalize”
This invalidates everything about Jeff’s piece except for his feelings, since the entire piece is an argument that there is a systematic problem with the team that other people have experienced too. There are tweets and quotes to support this.
Jeff does generalize, and he does reference other people who had similar experiences. Jeff’s entire reason for writing the piece is to generalize. He doesn’t say ‘I’m sure this is just me’. He argues quite the opposite.
If it is ‘not correct to generalize’ - as Mgechev says, then Jeff must be wrong about there being a problem with the team, therefore Mgechev does not believe Jeff.
You’ll notice that Mgechev repeats this ‘not correct to generalize’ here: https://news.ycombinator.com/item?id=25072705
Mgechev also says they “can't relate to his experience”. They also make no reference to (or validate) any of the other people who apparently had similar experiences or views of the team.
It’s pretty reasonable to conclude that Mgechev doesn’t think there is a problem with the team and wants to convey that to us.
https://www.merriam-webster.com/dictionary/generalize
It has nothing to do with ‘applying to all’
It means ‘to draw a general conclusion’.
Mgechev is telling us not to draw a conclusion from Jeff’s piece.
It is completely reasonable to assume that Mgechev doesn’t believe Jeff’s conclusions, and is asking us not to either.
> Mgechev is telling us not to draw a conclusion from Jeff’s piece.
You're really going to pull out a dictionary on me, then blatantly ignore the emphasized word in your chosen definition that is exactly the word that makes my statement true?
https://www.merriam-webster.com/dictionary/general
> general: involving, relating to, or applicable to every member of a class, kind, or group
2. Exactly one out of the 7 definitions on the page you list supports your position.
3. The top definition on the page you linked is consistent with the meaning I am using.
4. Saying the definition you have chosen is my chosen definition is a misrepresentation.
Therefore: You are the one selecting a narrow definition to suit your purposes.
Here are the tactics you have used so far:
1. Narrow definition.
2. Ignoring context.
3. Gaslighting.
4. Personal attacks.
This is the other side of the coin from Mgchev‘s comment.
As for anyone interested in real world comparisons of many of the popular frameworks (though not necessarily the most bleeding edge versions), feel free to have a look here: https://github.com/gothinkster/realworld
The last time someone did a writeup on the results was in the March of 2020, but even then Angular wasn't necessarily that big in the bundle sizes that it generated: https://medium.com/dailyjs/a-realworld-comparison-of-front-e...
Though the situation can indeed worsen as you introduce more and more libraries into the mix and as the project grows.
This answer doesn't quite cut it. Every project starts out as an "hello world" type application. How do you audit the cost of each additional package if you didn't even start out with a "small bundle size" from the beginning?
I believe you guys have made great strides and I appreciate your efforts immensely. I wish you the best of luck, I hope you're able to actually address the large size of deployment in a meaningful fashion.
I've heard my partner swear at least a couple of times a week over this since we've started working from home due to corona.
I was development lead for an angular shop. We did all the government Ministry of Health forms in Angular, millions of residents would use our forms every year. Our frontend team I lead fluctuated from 5-8 people over the years. We had to work on basically every device, making sure it'd work on IE11 and for blind users running screen readers is something we'd do every single release. I say this not to brag, but just to say I lived and breathed angular for years, I was hired as the "angular guy", and I even wrote an npm-publiished library of re-usable components specifically to match Ministry of Health forms.
My opinion of the Angular team and their stewardship of the project had ranged from mildly impressed, to disappointed, to alarmed. They frequently missed their own targets, the big one being Ivy, their compiler, which got pushed back 2 full releases and was constantly plagued by issues. (I left that job right as Ivy was released. Is anyone using it? Has it been a success?)
Like you, I saw the Angular team constantly speaking to compiler optimizations, but never once saw those benefits manifest. To be honest, it just felt like they were using the typescript compiler (tsc). I never saw any performance benefits over tsc. In fact, now using React/tsc/webpack, I feel like the compiler is more configurable and powerful.
In around 3 years of Angular updates the only feature we really used was the improved lazy loading of modules. I also used a bit of their codegen stuff ("Schematics"), which was promising but incomplete. Even though they were in release notes at the time, they lacked documentation and seemed like the team was bragging about features that weren't ready for light of day[0]. In the same timespan (~2016-Jan 2020), React got: server side rendering, pure components, hooks, profiling tools, improved lazy loading, and many _measurable performance increases that benefited projects across the board_[1].
Also, the Angular team began to increasingly focus on Material integration. We were a Bootstrap shop (ministry, at the time, required bootstrap styling). It was disappointing to see all those updates and know we couldn't use them.
I will say that generally speaking Angular's opinionated, more enterprise-y approach to frontend absolutely has a place. For certain workplaces, like my former big corp one, having an opinionated enterprise-y language made onboarding easier and devs more consistent. The most disruptive devs we had were hotshot react devs who wanted to make our Angular code base look like their flavour of React. I use React now, and love it, but there are pros and cons to having an opinionated framework/library (not having that fight).
And worst of all, the team itself seems to be imploding and toxic as you've alluded to.
I left that job for other reasons, but I'm glad I'm working with React and Vue more heavily now.
[0] https://medium.com/@lifenshades/difference-among-angular-8-7...
[1] https://en.wikipedia.org/wiki/React_(web_framework)#History
edit: The other great part about the Angular community is it's TS first. I miss that about React/Vue.
- Small: 30% - Medium: 2% - Large: 25-40%
Our initial Angular 1 bundle was around 1mb. After updating to Angular 2+ it was around 2mb and after leaving the company in the hands of developers who were fairly junior I can see that their main bundle has now grown to 2.8mb. Another project with various junior devs has 2.9mb.
This is what is frustrating when I see our sister company pull out a 1mb react app with little effort... No matter how much effort I put in, it's never going to be achievable. Our package.json is extremely conservative as well.
https://blog.angular.io/version-9-of-angular-now-available-p...
If you look at projects that try to be all-encompassing (e.g., like MeteorJS or Angular), you'll see a similar story line. To achieve everything they set out to do, the stars must align: ample staffing of the team, good architecture/design decisions that need not be reverted later, etc.
Having gone through this with multiple technologies, I am now skeptical of projects that over-promise or are too widely scoped.
> There's never anything obvious when it comes to analysing the bundle and it seems we're using everything we need: Angular, Material, RxJS
Yeah, that's exactly the major sources of bloat in Angular. Angular's runtime and core components are extremely fat despite how much they keep claiming is compile-time optimized. I'm terrified to look at the source for HttpClient because I cannot imagine how it possibly is big enough to explain its huge {minimized, gzipped} bundle size. That's just one Angular component in the vendor chunk that "has to be there".
Angular Material is another huge source of bloat and a lot of what I've been doing is removing it as much as possible. It seems like everyone throws in Angular Material feeling like it is a "best practice", but "no one" seems to like its styling or behaviors out of the box, put a ton of work into redoing its styling/behaviors in a complicated and bespoke way in nearly every usage and end up burying the already extremely bloated Angular Material components under whole new onion layers of their own bloat. Every time I dig into one of these bloat onions I seem to find it easier to write a fresh component from scratch and get rid of the Material dependency altogether.
RxJS is also huge, and it's a grand source of continuing disappointment with Angular how wishy-washy it has been with respect to Observables. If you are going to require a giant library like that, at least commit to it. Of course if Angular actually committed to Observables that might lead to using a lighter library instead of bundling the kitchen sink that is RxJS. (For several years I worked in an Observable focused React-like called CycleJS and one of the big moves CycleJS did primarily for bundle size reasons was switch to an "RxJS-lite" library named xstream.)
As someone that actually understands (and heavily uses Observables) it just absolutely floors me at how bad Angular is with them, almost like it is designed to encourage the worst practices for RxJS/Observable code. I see so many components manually (and badly) subscribing and unsubscribing from Observables that should never need to, sometimes simply because the authors weren't aware of the "| async" Async Pipe. (And why should they be, pipe documentation is almost hidden and yet another twisted part of Angular's template syntax with no relation to Typescript syntax despite appearing in places designed to look like Typescript?) Async Pipe is mentioned like a footnote in the Observable documentation that nearly everyone skips past. It should have been the default (or better yet the only way) in the template language: you have Observables, change detection, even "AOT compiled" change detection shouldn't be necessary! Observables should easily replace change detection. Zone.js is nearly entirely bloated redundant nonsense that shouldn't ever exist side-by-side RxJS, and would never be necessary if everything were Observables. It's almost a painful joke at this point how badly Angular makes use of Observables, how it works twice as hard to do half as well if it merely committed to Observables and only Observables instead of this half-Observable slash old school template change detection beast that it is today. Pick one and commit to it and so much bloat in Angular would just go away.
I have the same problem where people are doing backflips to do simple things and I'll come in afterwards like... What ARE you trying to do here? And why are you not cleaning these up?
Originally I was trying to stay away from behaviour subjects as recommended by the RxJS purists but now I just want to use them everywhere so its easier for everyone else to get values out of a stream
Half the component examples I see in the wild use RxJS wrong or badly, and of course that stuff gets copied and pasted everywhere.
I've already sent patches to at least a few documentation examples that are supposed to be "best practice" that failed to actually live up to best practices because Angular failed them in setting a good example to live by.
Angular has created the worst of both worlds that makes RxJS harder than it should be by failing to use it properly (providing too many bad habit escape hatches and failing to commit to it), but also making it almost impossible to avoid and subsequently polluting the entire ecosystem with bad examples, worse documentation, and terrible habits (all of which goes right back up to the top and terrible design decisions such as Angular core's EventEmitter).
If Angular committed to being an AOT change detection only system it would probably be much more like Svelte. If Angular committed fully to RxJS it would be something different entirely [0] and maybe sure it would be harder for a lot of devs to grasp at first, but instead of the pit of failure that currently awaits devs trying to learn RxJS in place in Angular, maybe they'd have a pit of success that a lot more devs would learn RxJS given a safe place to do it with fewer papercuts and bad examples to learn from.
[0] It probably wouldn't be CycleJS either, as they'd still probably avoid Virtual DOM techniques. This thread has me picturing what you could do with a compile-time template Observable pipeline and I'm almost curious enough now to build a prototype of it just to show Angular how dumb it is and what it could be.
Then you have the way universal replaces all content when it bootstraps and you get penalised for that. We're also seeing issues where the site isn't ready yet and clicking a link just opens a new tab cause the JS wasn't downloaded/parsed yet.
You can use the preload library but guess what: doesn't work. As usual it was always: this'll get fixed with ivy and it wasn't. It seems all libraries we depend on were initially made by staff who were driven out of the team. - universal - animations - forms
Our clients use the Google performance scores and ask why none of the performance improvements we're doing has had any effect and then point to a React competitor's lighthouse score
- Observables. I'm actually okay with observables, but it seems like Angular has tried to ride on both horses when it comes to observables. E.g. the `HttpClient` returns an Observable, but you can't get your input as Observables, so you have to do weird lifecycle workarounds to get observables re-computed as your input changes
- No fragments. Each component always creates it's own HTML tag. This makes stuff like having components inside tables really difficult to get right.
- The reactive forms has been untyped for years. It feels weird to ship with a forms module that seems to work pretty well, heavily invest on typescript, and then the forms are simply `any` - I mean what the hell?
- The input/output model is unfortunately much worse than it is in React. It doesn't seem like it, but the moment you want to create a HOC, or you want to wrap a component in another component, you find out that you have to manually specify all the input/output of the component you have to wrap. Nesting components is so inconvenient that your components become much larger than you want them to.
In templates is the biggest example - where you can use some JS constructs but not others, and have to learn a new set of directives instead of using if/for/while etc.
But also things like modules being an empty class that's only there so you have somewhere to put your annotations.
Not to mention needing to bundle a compiler, unless you use AOC, and the debugging is a nightmare (or at least used to be, I don't know if they've fixed it recently.) When your stacktrace is full of zone.js calls that are doing weird things because they monkey-patched Promise, you get the feeling that it's just not Javascript.
Some might say that JSX in React is similarly not JS. I respectfully disagree. The syntactic sugar is so light you could easily translate it yourself, by hand. Try doing that with Angular code!
And the trouble is that, as a new language that you have to learn, it is significantly inferior to JS/TS. So yes, give me React any day, where I can use real Javascript and not have to feel like the framework is fighting the language it's written in.
>In templates is the biggest example - where you can use some JS constructs but not others, and have to learn a new set of directives instead of using if/for/while etc.
Templates, just like JSX have their own trade-offs. They are statically analyzable, so relatively easy to optimize by our tooling. Having HTML templates allows us to generate efficient JavaScript instructions for rendering and change detection.
This has almost zero overhead on runtime and lets us perform change detection as fast as possible (we know exactly what has changed in the view).
>Not to mention needing to bundle a compiler, unless you use AOC
You don't need to bundle a compiler in Angular. The compilation happens at build time. After that we perform a lot of optimizations (having JavaScript instructions instead of HTML templates allows us to tree-shake more efficiently).
>debugging is a nightmare
Browsers hide the part of the stack trace that's coming from node modules, others let you blackbox non relevant scripts. To ensure smoother debugging experience for folks, we've been also working on providing better debugging guides and development tooling. We'll be rolling this out in 2021.
>And the trouble is that, as a new language that you have to learn, it is significantly inferior to JS/TS. So yes, give me React any day, where I can use real Javascript and not have to feel like the framework is fighting the language it's written in.
As I said above, it's all about trade offs. JSX is very expressive, but sets its own limitations. It locks you to a specific paradigm for incremental computations, which is not necessarily the most performant one. Templates are less expressive. At the same time, they are easy to optimize ahead of time. Neither of both is JavaScript, as described by ECMA-262.
Comparing templates and JSX is definitely an interesting topic that's hard to cover in a comment on HN :)
My main point isn't so much the individual difficulties like debugging, yes you can build something on top to fix it. It's that these are symptoms of not respecting the idioms of the language the framework is built in. This leads to everything working fine if you do it exactly by the book, but when you start deviating slightly from the standard Angular way of doing things, the cracks start to appear.
This wouldn't happen if it was written to work with the language rather than against it. There's no good reason why me setting my own setTimeout() without going through Angular's should break things, but it does (and Angular reports my app as 'unstable'). If I have a getter method on my component that gets called thousands of times a second by Angular to see if something changed, it's another symptom that the framework wasn't written to fit neatly together with the language.
The fact that you can add yet more code and tooling to handle these issues as they come up does not alter the fundamental problem.
I'm really interested to know how many JS or DOM builtins Angular modifies, wraps, edits the prototype, or replaces in order to work. I know it modifies Promise, I think setTimeout too, and probably also DOMElement. @mgechev, would you have that information?
I personally tend to agree with you, but I think there are use-cases where the Angular philosophy can be the right decision. The key differentiators for me are a) does this walled garden provide real benefits over the more open model? b) does the organization backing this project have the resources to re-implement and maintain standard library functionality, build/editing tooling, debuggers, documentation, etc? There is a very high cost to going this route, because so many things move in-house. In Angular's case, backed by Google, the answer to question b is probably yes. The answer to question a is less clear. It sounds like there are performance advantages, and certainly there's a cohesive dev experience. For some companies, this tradeoff may be worth it. Personally I wouldn't want to use Angular, but I respect their decisions for what they are.
Aside: I wrote that blog post after being faced with a framework that's very similar to Angular, except it's backed by a very small team unaffiliated with a major tech company and is barely being maintained at this point. That's pretty much the worst-case scenario; with a more open "library" you'd have a much easier time coping with a loss of official support. But Angular is unlikely to ever find itself in that kind of situation.
AngularJS (v1) found itself in exactly that situation! But it's true that it doesn't look like new-Angular is going that way (at least not yet).
Sort of. Angular 2 came out in 2016, and Angular 1 will continue to get long-term support through 2021. That's a pretty generous window, and there's also a clear and well-documented migration path. Overall it's a dramatically better situation than the one I found myself dealing with.
You're getting warnings at devmode (i.e. during ng serve) that you've modified a binding after it was checked. This is not related to the way we trigger change detection. The simplest example is:
@Component({
template: '{{ foo }}'
})
class AppComponent {
_foo = 0;
get foo() {
return this._foo++;
}
}
This is clearly unstable because every time we get the value of foo, we also increment _foo. What Angular does in devmode is to ensure developers are not hitting this issue.This is not related to setTimeout and the APIs we patch with zone.js. The check just safeguards us to not get into such cyclic binding scenarios. We'll be working on better explaining the error and the message in future releases.
DOMElement is untouched, we only patch APIs so that we can plug into the microtask queue and trigger change detection when it's empty to ensure consistency between the model and the view.
In fact, one of the projects high on our priority list is to make Zone.js optional and provide alternative, ergonomic APIs to trigger the change detection and specify local component state. I am saying ergonomic APIs because this is already possible, just not ideal since we have to specify a noop zone when bootstrapping the app. Optional, because many developers love the current behavior and we want to keep it available.
And just, let me spent one more paragraph in explaining how the change detection works. Just want to show why is it that fast and with such a low memory overhead.
Each component has a template that we translate to JavaScript instructions. For example:
<span>{{ foo }}</span>
We will translate to something like (I'm writing the comment from my phone, some instruction names could be different in the CLI output): if (mode & creation) {
renderElement('span');
interpolation(ctx.foo);
} else if (mode & update) {
interpolation(ctx.foo);
}
That's a leaf component, but we can imagine how it works in more complicated hierarchies.So when we trigger change detection we just invoke the template functions for the components in update mode. We update only the bindings that have changed, without allocating any additional data structures to do that.
Whether the framework is written to fit the language is mostly a subjective opinion.
Angular doesn't go against the standard anywhere and does not introduce extra syntax on top of TypeScript. It also doesn't add new semantic to already existing constructs.
In fact, to keep compliant is from a high priority to us. We constantly interact with different standardization bodies and keep up to date with standards.
Yes, the basic template update mechanism is fine, and it does seem to be fast. I was talking more about the change detection, how it knows that foo has changed in the first place, particularly if it is a nested object or a getter that leads to one. I have had cases where Angular calls the getter constantly (proved by console.log).
I agree that there isn't another obvious way to figure out something changed, but that's the point - since JavaScript doesn't have a way to notify on changed properties, for the framework to make that the paradigm is an interesting choice. So it's great news that you're moving away from that and from zone.js.
This is where React's setState is much easier to reason about. I call a function, I know that I told React that something changed, so the update isn't a surprise. While setting a property does not usually cause anything to happen in Javascript, so I have trouble getting my head around how it works and what Angular is doing behind the scenes, and realizing that it must be polling, which isn't usually a good pattern.
> In fact, to keep compliant is from a high priority to us. We constantly interact with different standardization bodies and keep up to date with standards.
Which is definitely a good thing, but also an indication that it's not actually Javascript, just something that tries to be compatible with Javascript.
Anyway, thank you very much for responding! I also understand that Angular has a lot of history to work with and you're doing a good job with the paradigms you have.
As a rule of thumb naive change detection is fine for a small app, but if you want performance, just opt out of the default and manage it yourself: https://angular.io/api/core/ChangeDetectorRef#usage-notes (and probably you have a component that spams changes, where you should completely opt out: https://gist.github.com/jhades/269ee42b83937418e0dbe00e49413... )
Also, I don't think they're moving away from zone.js. They are simply providing an alternative for the more minimalistic minded folks, who like to put their own stack together.
> While setting a property does not usually cause anything to happen in Javascript, so I have trouble getting my head around how it works and what Angular is doing behind the scenes, and realizing that it must be polling, which isn't usually a good pattern.
... um. It's a bit ironic that you say that Angular is going against JS, but maybe you forgot about the wonders of Object.defineProperty which allows the unflinching true hackers to virtually override assignment operation itself!
But Angular doesn't work that way, saner heads prevailed apparently. Hence the use of TS annotations, like the @Input property, which basically wraps the field to trigger change detection. And zone.js, which ... well, basically it does work that way. (It simply replaces global objects with a wrapped version. It wraps timers and I/O, as in click, type, touch, fetch, and websocket events, and who knows what.) So no polling, but yes monkey patching.
Nothing in Angular is first-class because nothing in Angular is endemic to JS. Some are not bothered by this. Personally, I get frustrated without first-class features because I don’t feel like I can put my back up to any part of the language and be 100% sure of how it’s going to work/compile. Even worse, the hybridized language becomes a nightmare to debug since everything has to go through the Angular pseudo-VM.
You might find that something like lit-html is even more like vanilla js, while being, I believe, statically analyzable.
"Inputs as observables" is probably the most discussed feature request on our issue tracker. I agree that there are strong arguments for going in this direction, but we generally try to keep `@angular/core` agnostic in this sense and not couple it to RxJS (EventEmitter is the only dependent abstraction right now). There are different reasons for that, but I'd say the two main arguments are: out of order component loading and ergonomics.
There are a lot of developers who are comfortable with RxJS and enjoy how expressive it is. Simultaneously, we have a less vocal majority of either beginners or people who oppose such expressive APIs. Both of these groups use Angular, and we need to keep the framework ergonomic for them.
That's why we have community libraries such as `ngrx`, which we consider as reactive extensions of @angular/core.
>- The reactive forms has been untyped for years. It feels weird to ship with a forms module that seems to work pretty well, heavily invest on typescript, and then the forms are simply `any` - I mean what the hell?
We developed reactive forms when TypeScript was still not as powerful as it is today. For the past years, however, the language evolved and it has very strict and expressive type system.
We really want to make reactive forms much more struct :) Our team has been looking actively into that, but it's not trivial to fix the problem without introducing breaking changes in the public API surface. That's something on our radar, and we've been doing a lot of exploration, but given the adoption of Angular, we want to be careful and land it without breaking the ecosystem.
In the meantime, we have community modules that provide much stricter forms implementation.
Regarding fragments and the input/output model, we haven't received much of your feedback, but that's something I'll bring up to the team.
Re: inputs as observables: Yeah I've followed the Github issues and while I get the arguments, it still seems weird that the value prop of Angular seems to be "batteries included", that the batteries then disagree with eachother.
I totally get that you have two camps of people using the framework, but right now it feels like the state Angular is in, leaves both camps satisfied. The people who like RxJs can't utilize it fully, and the people who don't still have to deal with it.
Re: forms: It makes sense that the forms are hard to type without breaking stuff. Stuff being third-party is probably one of the reasons the React eco-system has been able to move faster, but also with more breakage. That's probably just a consequence of the different ways to govern the project.
Re: fragments/host elements: There's a two year old issue here with 200 or so upvotes: https://github.com/angular/angular/issues/18877 I'll admit that this is probably not the biggest issue - I've only encountered it because I wanted to have sub-components within tables and that can mess up the formatting.
Re: input/output model: It probably makes sense that you haven't heard too much about it. It's probably not something you'd necessarily think about if you just developed angular and haven't tried other composition models.
It's not impossible to make forms stricter, it's just a matter of planning how to make it in the least breaking way. Definitely from a very high priority for us.
Reactive Forms are really great in general, but not being strongly typed is really a shame. I am aware though that it's not easy to actually make it strongly typed for various reasons.
For a component-based framework, it's way too tedious in Angular to actually create components. Too often I create big components because I can't bring myself to split it into smaller components. In React it is so natural to create components you can do it even while you develop a feature (without it being overhead). I hardly do that in Angular because it's just too much work.
I agree 100% with the big components. I can literally feel myself thinking "I should split this up.. but it's so much work" - where there's just much less friction doing that in React.
I ended up with a service that doesn't rely on observables.
I also didn't like using observables with Angular to fetch/send data to API's. Not everything is an event stream, why can't we use the right tool for the job?
Strict type checking is often reported as confusing for folks getting started with Angular and web development. That's why by default our type checking is not the strictest we support.
To make sure advanced developers have better compile-time type checking and editor support, we introduced strict mode. When you create a new workspace the CLI asks you if you want to get it enabled.
In the future, incrementally, we'll be enabling strict settings for everyone.
It still seems strange to me, if you start a new Angular project then you know you're writing TypeScript, no ifs or buts - and that means if you write some code that doesn't compile, you'll have to fix it before it runs. I don't understand why that's seen as different in the template layer?
Great that it's there at all though, last time I developed with Angular templates didn't have type checking at all, and it kind of hurt.
To get the same strictness as in TypeScript, you can enable `strictTemplates` in tsconfig.json. Here's our guide which goes into more details https://angular.io/guide/template-typecheck.
I think the idea is to provide a single async abstraction so everything can be used with rxjs operators. I've taken advantage of this several times with something like "combineLatest" to return the result of a http call and an event stream.
You can also call "toPromise" in rxjs to turn an observable into a then-able promise.
On the Observables point, the Ngrx folks have created the @ngrx/component[2] and @ngrx/component-state projects[3] to try to build true reactivity into the component model. It's a shame this effort is happening outside of the main project, but it's something.
[1] https://angular.io/guide/roadmap#better-developer-ergonomics... [2] https://ngrx.io/guide/component [3] https://ngrx.io/guide/component-store
(I have not used angular myself)
Same about Reactive Forms.
Patching each @Output and @Input through a component by hand is also pretty annoying, especially if they change relatively often. A custom input field for a reactive form gets quite large due to all the in- and outputs.
Patching @Output and @Input is supremely painful - I really wish there was some sort of shorthand for that.
Inputs into makeObservable are the component class (this) and the requested property name (generics with keyof).
Within a components template though, I frequently use <ng-container> to execute async pipes, or to perform simple conditional logic without adding unnecessary divs.
I'm intrigued about you not agreeing with the last part though. You don't think it's painful to manually reroute inputs/outputs to child-components?
And on npm it's gaining popularity: https://www.npmjs.com/package/@angular/core
React is still the clear winner in terms of market share, but Vue.js and Angular are very popular and not going anywhere. Fortunately, there's room in the world for more than one front-end framework.
Having used Angular professionally for several years, and React for the past two, I think both have clear strengths and weaknesses, but informed debate is sadly lacking, and instead we have a lot of partisanship and uninformed opinions.
Vue has a similar track over the last year https://www.npmjs.com/package/vue
React is gaining even more quickly https://www.npmjs.com/package/react
The fixed release schedule means that, at times, the "what's new" section is a bit meagre in the major releases, but e.g., the recent release of Ivy highlights that this is more of an artificial issue than a real one.
I'm personally very happy working with Angular and have chosen to use it even when provided the option of moving to React or Vue. Each of the major frameworks have their strengths and weaknesses, but I feel that we've reached the point now where their maturity is such that you cannot really make a fatal mistake in selecting either of them. Your use case and your team makeup is much more decisive.
I get why they felt like they had to do it (the Angular 1 codebase originating in 2009), but they should have gone for a much more smooth and gradual upgrade path.
If I would create a (realtime) data intensive app, I would probably use Angular for it.
a) Over-engineered and an entirely unnecessary level of abstraction and flow control for a web app
and
b) A total spaghetti mess of event handling code all over the place and no way to tell what the flow of events is and always having to hunt down difficult to debug issues as a result.
RxJS may be neat, but it's definitely architecture astronaut territory.
(I also think async generator functions are a great tool for reactivity that are underused)
Anyway, there's a huge amount of extra language that you need to develop around RxJS...at first I didn't mind because I thought I was getting multi-language benefits: "Oh! Reactive Extensions are available in a variety of different languages! Sweet!" But the specific patterns and terms learned in one implementation tend to be vastly different than in others. Sure, you're still working with the same patterns at a high level, but don't expect any of the same methods to be present or even the same basic syntax, even if the languages are similar.
Has cycle got any real-world adoption, apart from Andre writing the Manyverse client in it?
But as I wrote in the comment before, while Cycle.js is in my eye the cleaner UI framework implementation with observables (compared to Angular) it has a very small eco-system.
Is there development though? It looks like since 2018 there have been only minor updates, and major projects like [1] are still just a dream.
On the other hand, "sponsoring the development" could be a strong word. Giving a few bucks every once in a while isn't really sponsorship [2]
With comprehensive frameworks, I always think of this as the Smalltalk problem.
In real world use, aggregate framework dev-hours typically trump superior architecture. Sadly.
That’s funny, because for the exact same reason I’ve taken a strong dislike on it.
The rest of NodeJS flows on promises and constantly have to switch between that, and having to use different APIs, and no longer be able to write simple awaitable async code...
It drove me mad. Angular without RxJS would be so much better.
As far as my experience goes, promises require some extra work too.
Developers in these environments usually do not take part in these surveys.
Angular team member here. These are our observations as well. Based on metrics we collect (opt in telemetry, website traffic, language service downloads, etc), there are over 1.7m developers using Angular.
I'd say that many of them are in the enterprise, but there are also a lot of startups that bet on Angular. This is mostly due to the integrated stack where folks need to make fewer decisions and get smooth updates across versions.
Stability is another factor. We validate every commit pushed to the Angular repo with 2600+ projects inside of Google. If any of their tests break we rollout automated migrations or rethink the implementation.
All the mainstream frameworks are great tools. I'd say if you're looking at React, Vue or Angular and think "Dunno why anyone would use that, must just be the "we've always used x here"" than I'd say rethink your approach to "it's probably a good tool for their use case".
I have never witnessed an evaluation or discussion of tools for a project. Ever. Neither open-ended nor otherwise. I’ve worked on diverse projects for various clients (since Angular 2 arrived) and Angular was either an explicit requirement by the client or a team decision. There were no arguments, ever.
The people I worked with were never particularly knowledgeable. In fact, for non-trivial use cases, I feel that Angular is actually hostile to young professionals. RxJS in particular is a topic I’ve seen people struggle with a lot.
Can you achieve success with Angular? Absolutely. I don’t feel it’s any easier than with React or even AngularJS though. (No experience with Vue.)
I am not sure about that, it is more that the full stack of technologies for current SPA is daunting for new developers.
When learning react one just go to one part at a time, first rendering, then props, now learn to use the router library. When using angular one can feel overwhelmed because all the panel of tools is presented in one repo.
Anecdotal: when Angular (1.0) first came out, it felt professional and mature; you could clearly define your components and write a complete unit test on top of that. It fits well in an enterprise environment where developers are taught to do the same with (usually) Java classes.
I've consulted for a company once where they wanted to rewrite their UI in web technology; we did a POC for React, Angular, Vue and Ember. In the end, they went with Angular because they felt the most comfortable with it.
You could be right, I can see how arguing with component instances etc. can be easier when you come from object-oriented GUI platforms.
React only gets used when FE devs overweight the full stack ones. At least on the projects I have been involved with.
This is why I liked Elm as well because it bakes in a particular structure and adds static typing.
The other advantage is if you're hiring freelancing. From personal experience, anything that was custom and less opinionated cost more billable hours. Dealing with a framework like Laravel, Django, Rails cut costs in a noticeable way and the remaining work was actual hard problems to solve.
But if it's about having the font directly in the bundle encoded in base64 to save a http request, you can do that with webpack for example. But from what I understood, base64 encoded content is often slower to load than the same content served over http 2.
I don't know if others are automatically downloading the fonts to include them in the build. It's a nice feature but you can also install many Google fonts from Npm.
I guess the "innovation" here is that they also support the download step?
Either way, fonts are bulky binaries that don't gzip well but do cache well in browsers when combined with central CDNs so this seems an anti-feature for reasons other commenters point out. Most common fonts are going to be faster to paint from the cached CDN than letting it bloat your bundle sizes.
The React team at Facebook has their act together and does a great job. The new Facebook redesign with chunks is really amazing.
React hooks I think as they are currently designed is an anti-pattern because of the way they're too 'magic' and can bust the cache accidentally and cause performance bugs but conversely can cause data loss bugs because your code doesn't properly use hooks.
Bad use of an API should yield compilation errors (in Typescript) NOT cause all sort of runtime errors with caching.
Which brings me to where I disagree with you that React team has their act together. If anything, the hooks API is tacit acknowledgement that they messed up on component lifecycles and their original component model and really don't know what they are doing. If you go back even a year earlier, most people seem to have forgotten that they redid their entire set of lifecycle methods before scraping it all for hooks. They haven't been able to get a stable API together because, architecturally-speaking, they don't know what they are doing.
The only alternative explanation is that hooks is the React team trying to remain relevant through a misguided API "refresh". Which is definitely not a good look for anyone wanting to take a framework seriously. Outside of Facebook, literally no one has the money to rewrite their app every year. Hooks aren't even backwards compatible. It's not even self-compatible with its current version! Since you can't mix hooks and classes. Just insane.
I feel like the React team did a bad job at communicating that the functions are still stateless. The functions themselves never hold state, they just access the state that react holds for each component through hooks.
I think this confusion is further fueled by the fact that most people feel
render () {
return <Button />
}calls the `Button` function inside `render`, but what it actually does is that it registers the `Button` function in React, telling it "here's how you can create what I want", it doesn't actually call the function. The actual call is done by React, if and when it wants to.
Hooks extends that idea by letting you say "Here's how I want to update my component".
The component functions you write in React are a "description" telling React how to create that component. With hooks you can now "describe" how to update that component with new changes. I feel like hooks force you to let go of the control you thought you had with class-based components. Whether that's a good thing is up upto you.
So, a closure?
I see gripes about hooks mostly on hn. Most of the industry loves it, and for good reason. There is nothing to „understand“ about hooks. You don‘t have to think about what should happen when. Just use hooks to get what you want and forget the rest. If anything, it‘s easier than before.
[1]: https://reactjs.org/docs/hooks-rules.html [2]: https://reactjs.org/docs/hooks-faq.html
The problem is that Angular 1 is VERY different from Angular 2+ and searching "Angular" gave Angular 1 results... the search index of Google was poisoned for so long with the wrong results that I switched to React out of frustration.
We moved to RiotJS which was a breath of fresh air... for a little while. Then the same problems started plaguing that project in terms of major breaking changes so we hopped ship again.
Now, we are on top of Blazor using server-side rendering. Our hopes are that by taking up allegiance with Microsoft that we can ward off horrific breaking changes for a few years and actually build something valuable during that time. Blazor is particularly appealing to use because we were able to completely define our UI state machines in C# classes that can be tested in perfect isolation from any client/browser interaction. We can also directly inject & reuse our existing business services without needing to develop any JSON APIs or other wasteful boilerplate.
Ironically, I like them because they remove the magic from state management. I really enjoy using and writing hooks.
Webpack 5 and its persistent disk cache.
Much cleaner build reporting. It has been always annoying to keep an eye on them hidden and shuffled in the build log.
Inlining fonts, yesssss. Excellent work.
Seeing ngcc speed improvement even by 1% is great where it seems to be up to 4x speedup.
We have bit Angular code base and smaller ones and every single of Angular features in this release is helpful regardless of the size of the code base.
Thank you Angular and everyone involved <3
It's possible I haven't hit any of the downsides yet. With that caveat out of the way, I will say that I absolutely love it after using React for about 5 years. Here is why:
1. It's simple. The API can be read and fully understood in a day or two. The documentation is clear and their examples are simply wonderful. Seriously. Go through their tutorial (https://svelte.dev/tutorial/basics) or their examples (https://svelte.dev/examples#hello-world) or even their API docs (https://svelte.dev/docs). It's all well-crafted.
2. It has CSS modules built-in. You don't need to install anything or configure anything. You insert a style tag, write some CSS, and your component gets style without stepping on global styles.
3. It has state built-in. It has a dead simple state protocol. You can even recreate a redux clone in about 20 lines (https://monad.fi/en/svelte-custom-stores/).
4. It's compiled, which means it can do things other frameworks can't. Which also means you get actual messages from the compiler telling you what you are doing wrong and what you should be doing. The messages I've seen so far from svelte are easily some of the best compiler messages I've ever seen.
5. Minimal edge cases. There are a few edge cases (e.g. arrays and reactivity), but it's fairly easy to know when you're hitting one.
6. Way more flexible than React. Event forwarding, event modifiers, boolean class names (i.e. class:large adds the "large" class if "large" is bool and true), ability to create generic actions that can be added to any DOM nodes. Animation support built-in. Variable binding, makes it a breeze to create any form.
Sapper is going away, but SvelteKit is being worked on. If you really need more than Rollup+Svelte.
They are similar in a sense that both compile HTML to incremental DOM-like structure, but have their own differences.
Haven't heard anything about Svelte in months / years, although usage is steadily increasing (https://npm-stat.com/charts.html?package=svelte&from=2017-11...).
Im not 100% sure how it'd look, but I reakon with Kotlin Multiplatform you could have a full stack application, all in one multi-module project, all in the same language, in a language not dervived from Js.
One to aseess when I get some time.
Frameworks maybe make more sense from an organisation perspective of having to create the same thing in different variations but for sheer simplicity & understanding of what's actually happening plain JS/jQuery seems like a breath of fresh air.
That is what angular solves for me, I don't have to spend time introducing new person to the project structure. I don't have to argue with "I know better juniors", I don't have to deal with condescending seniors "who wrote it that way it is total mess".
Maybe you have seen some project handover to different team or you got project inherited from someone. It will be a lot easier to understand if that other team speaks "angular".
I don't say code is perfect, you can still write total mess with it, but having angular saves a lot of digging into some insane monstrosities that I have seen in jQuery.
In the end you might never need it, because everyone has different requirements and different projects.
Something simpler than ng/React, yet able to compose architectures with plain JS, all without compiling front-end.
I see they're pushing one release a year. Last release was in April/May.
I hope it's being maintained.
At this point, I view jQuery as a foundational library.
I know newer versions of HTML and browser APIs are replacing some of the need for jQuery. But its ergonomics are universally understood. For me that's as important as the APIs themselves.
And I don't trust browser vendors to maintain uniformity long-term. Too many egos involved.
I hope jQuery never dies.
In Vue when a component has changes (e.g the user click or input something in the component), the reactivity autodetection mechanism will trigger changes on the component and its children/descendants.
Angular instead by using zone.js will trigger all the things that Vue rightfully trigger but they will trigger all of the component ancestors too! Up to the root! This means two things: You can't debug this mess as any method in the template or onchanges hook in the ancestors will be triggered and console.log() so the Devtools are flooded with unrelated changes. If you call a store on the template the store debugger will be flooded too.
And all those calls affect performance dramatically which is pure unwanted nonsense.
This non Scoped reactivity might have usefulness for 0.1% of cases (or for 0%?) but even at best, it should be totally opt-in. But the situation is worse, you cannot opt out. Or you can, with changedetection.onpush which disable any reactivity (you must manually trigger it in 2020, can you imagine?)
This nonsense made us stay on Vue and everybody in it's right mind should avoid Angular until this fundamental issue is fixed.
https://medium.com/@vyaron/point-of-vue-part-2-facing-angula...
Unrelated: the second huge limitation of angular is that it has no official devtool integration and that the community devtool is mostly unmaintained and doesn't work on angular > 9
Every time I see React had got shiny new pattern that breaks everything you have done so far or Angular is 4 major versions ahead of when I last checked and still not solving the architecture inconsistencies I'm glad I stayed with AngularJS.
I believe you must choose one based in the knowledge and experience of your team. There isn't really a real technological reason to choose one. In the long term, they all look the same.
Definitely still loving how productive our small dev team can be using Angular. Sometimes the "batteries included" approach approach gets a bad rap but I really enjoy it.
There are interesting discussions daily! Come join us at https://discord.gg/angular
Looking forward to Webpack 5 integration. A mature framework to develop enterprise applications.
I picked Angular because it was so advanced. I wanted the challenge, got to work on awesome teams, and learned so much. I'm a better developer today because of it.
Thanks, Angular!
With respect to "Angular 2", there's probably a comparison to be made here with Linux 5.x effectively being Linux 2.6.$BIGNUM; as far as I know, Linux major version bumps don't indicate anything more than a threshold of Linus's discontent at how much unsung change has accumulated since the last bump.
For more, see:
https://angular.io/guide/releases https://update.angular.io/ https://angular.io/cli/update
- v8: we added functions and streams. It basically changes everything. We also added asynchronous stuff but you don’t care yet.
- v11: we added built-in async http. Now you really want to have a look at that asynchronous stuff from v8.
And that’s pretty much it.
AnInterface<String, String> foo = new AnImplementation<>();
It's actually an incredibly nice language. It's easy to pick up, it runs literally everywhere, it's fast, it has good tooling, it's sane, it's super productive and it's quite actively developed.
AngularDart could have actually become so much bigger than it ever was and while it isn't in any danger of actually dying it may as well be since Google have made it clear that due to the lack of interest they are just going to more or less treat it like an internal framework.
I looked at it as a bit of a chicken and egg scenario. It's actually an incredibly mature and rock solid framework but they never seemed to invest much into even the basics of documentation. It was a total non-starter for newbies and never had a chance to get a lot of traction. If they had a proper budget put aside for dev-rel I feel that could have been a totally different story with a very different ending.
What FE tech would your company use nowadays for new projects? What would you use nowadays for new projects?
I'm sure the worst candidates almost always pick React too, and some of the mediocre ones.
People are just picking what they're most familiar with and that which is simpler to complete your task.