Replies: 33 comments 142 replies
-
What impact will Signals have on hydration and server-side rendering improvements that are both on the roadmap? |
Beta Was this translation helpful? Give feedback.
-
Why decorators are magic for devs? Why perfectly designed class components should be replaced with some "react style" hooks? Looks like angular has lost it's popularity and you are trying to return back peoples attention. I really consider that react hooks are mess. |
Beta Was this translation helpful? Give feedback.
-
With a Zoneless application using signals, will this negate the need to trigger change detection when writing unit tests? Writing unit tests for OnPush components by wrapping them in a host component is a common pain point for me. If going Zoneless with signals solves/simplifies this, that'll be amazing! |
Beta Was this translation helpful? Give feedback.
{{title}}
{{editor}}'s edit
{{editor}}'s edit
-
Will a zoneless application using Signals offer bundle size improvements over a zoneful one, or are they marginally the same? |
Beta Was this translation helpful? Give feedback.
-
Interesting times ahead for #angular 😁 |
Beta Was this translation helpful? Give feedback.
-
Really appreciate the thoroughness and thoughtfulness of this RFC. Look forward to digging into the sub sections. But, overall, I'm excited for this development in the framework, especially with regard to its impact on performance, and enabling teams to create more performant components without having to hand-hold change detection so much. Eager for a zoneless future. |
Beta Was this translation helpful? Give feedback.
-
I'm curious how using signals as a reactive base for Angular will affect a part such as "Reactive forms module", |
Beta Was this translation helpful? Give feedback.
-
I'm wondering how will the use of Signals affect Angular’s internals that depend on observables such as forms, router, and http client? |
Beta Was this translation helpful? Give feedback.
-
I think this will also pave the way to having functional components in the future. It is very understandable, and I imagine a component built entirely on signals would be way more readable and simple than a "traditional" one. |
Beta Was this translation helpful? Give feedback.
-
It's better to have some code snippets of signals with each use case in docs. Signals are beast 😍 loved it. Appreciating your hard work @atscott @alxhub @dylhunn @pkozlowski-opensource @jelbourn |
Beta Was this translation helpful? Give feedback.
{{title}}
{{editor}}'s edit
{{editor}}'s edit
-
Is OnPush directly correlated to ZoneJS, or are they separate entities? More specifically, can I utilize a library using OnPush and still be able to remove zone.js from my application running Signals? |
Beta Was this translation helpful? Give feedback.
{{title}}
{{editor}}'s edit
{{editor}}'s edit
-
I think this is the most exciting evolution of Angular since 1.0, and the evolution since 1.0 has been solid. I'm extremely happy with the overall design, and what it unlocks for Angular going forward - namely clearer code and performance. Kudos to the team members leading this effort for the thoroughness of these RFCs and the prior work to refine the concepts and ensure backward compatibility in the design. I've always felt that zone.js and the change detection model was the worst/clunkiest part of Angular - to clarify, zone.js is an impressive building block, but it and the change detection model are the hardest parts to understand and troubleshoot. In addition to potential hidden efficiency problems, there are unintuitive rules - eg change detection doesn't propagate unless inputs have changed or a DOM event has occurred; and host attribute/style changes require a change detected on the parent. It requires regular developers to have a deeper understanding of the internals of Angular than it should. So I've avoided relying on zone as much as possible, use Hindsight is 20/20, but it's clear to me that this is the "correct" approach for Angular, and is needed to make/keep Angular competitive with newer frameworks. |
Beta Was this translation helpful? Give feedback.
-
HI :) got this error while using fromObservable: "ERROR Error: fromObservable() signal read before the Observable emitted" I have to add a startWith as a workaround. Is this an on-purpose behavior?
|
Beta Was this translation helpful? Give feedback.
{{title}}
{{editor}}'s edit
{{editor}}'s edit
-
Awesome works from you folks! 🔥 Do you already have some vision on the long term plans? I mean, are you aiming (in a future version like 18 or 19 or 20...) to make signal based components by default (and standalone as well) which will imply the deprecation of input/output decorators and ngOnInit and other lifecycle hooks. I'm asking that because as the primary goal of what's coming since v14 is to reduce the learning curve and increase the traction I guess new comers will get confused if both worlds (signal based and zone based components) are living together in the framework, I'm afraid some developers might get discourage when asking themselves "should i go signal based or zone based" which will requires a lot of digging to understand the pros and cons (thus the learning curve will stay the same). I'm a fan of opinionated technologies and I hope Angular will stay opinionated and that we are currently in a transition to full standalone and signal based apps. 🫶 |
Beta Was this translation helpful? Give feedback.
-
Great work guys! I've played around with signals and I think you're getting it right. It feels like the good parts of Vue. One thing I thing we could do better is the value calls on primitives.
Could this be possible with primitive values? class WritableSignalPrimitiveConversionImpl<T> extends WritableSignalImpl<T> {
[Symbol.toPrimitive](hint: string): T {
switch (hint) {
case 'string':
return String(this.value);
case 'number':
return Number(this.value);
default:
return this.value;
}
}
} Sorry very rudimentary idea but maye using Symbol.toPrimitive could get the desired API? |
Beta Was this translation helpful? Give feedback.
-
How about using objects inside a signal? What do you think about it? can I use it? angular will support such a thing?
When I change |
Beta Was this translation helpful? Give feedback.
-
Is there a way to implement the signal change detection into the async pipe? |
Beta Was this translation helpful? Give feedback.
-
This feels like, we're reinventing the wheel... I mean: Angular is and was built to be reactive. The original idea was to use Signals are reactive programming but with a different syntax. More precisely, they are BehaviorSubject. Maybe we should let the things settle down, and provide a very robust paper: why Angular should move to Signals ? Are the benefits really worth it ? Are they other solutions, maybe better ? I mean, Angular is a widely used framework, mainly by companies requiring a stable, scalable, and robust framework. So we should not be blind, jumping from the latest trend just to attract "the cool kids". Angular's target should remain to focus on companies requirements, not on the "fun" and "latest" tool. They may be great, but they should not interfere with a long term vision. |
Beta Was this translation helpful? Give feedback.
{{title}}
{{editor}}'s edit
{{editor}}'s edit
-
RFC: Angular Signals
Authors: @alxhub, @atscott, @dylhunn, @jelbourn, @pkozlowski-opensource
Area: Angular Framework
Posted: April 3, 2023
Status: Open
(this is the main RFC document, which links to the others)
We teased this in February, and now it's time to dig into the details: the Angular team requests your comments on our plan to adopt signals as a reactive primitive for Angular.
Before you dive in
Background context
Before going further, it's helpful if you understand How Angular change detection works today.
What kind of feedback are we looking for?
While we're excited to hear any and all comments on Angular Signals, we have additionally called out specific discussion points throughout the RFC for directed feedback. When you leave a comment, be sure to note the open question(s) to which you're responding.
As always, keep our code of conduct in mind. We know that a proposal of this scope significantly impacts Angular and the way you use it in your projects. We appreciate your commitment and investment in this project and ask to keep comments respectful. Remember, we are all just folks doing our best with limited resources.
How this RFC is organized
Because Angular Signals is a large project, we've split this RFC into several smaller docs. We recommend first reading the overview in this document and then jumping to the more specific docs in order.
Goals
This is a big change to Angular, so it's important to talk about why we're choosing to take this step. As we began our investigation into reactivity, we set out several goals we wanted to achieve that we felt would greatly improve Angular, based strongly on developer feedback over the last few years:
ExpressionChangedAfterItHasBeenChecked
errors.We think the best way to achieve our listed goals is to add fine-grained reactivity to the framework with Signals.
An RFC in four parts
If you're interested in the choice of signals as the reactive foundation of the framework, see the sub-discussion RFC #1: Signals for Angular Reactivity.
If you want to discuss our signal API and implementation itself, see RFC #2: Signal APIs.
If you're interested in exploring how using signals will look in Angular, then start with RFC #3: Signal-based components.
And finally, if you're curious about interoperability with RxJS, see RFC #4: Observable and Signal Interoperability.
Wrapping up
That's it!
This RFC has been a long time in the making. We're excited (and relieved) to finally share the details. Whether you're a long-time Angular developer or just stopping by to check out this new buzz on Angular, we're looking forward to obsessing over your every comment.
We want to make a special thanks to all of the hard work and innovation that have inspired us in the web community. Signals are clearly having a moment in the discourse today. Our ideas build on top of a large body of work– Preact, Vue, and SolidJS in particular have been inspirations for this project.
Frequently asked questions
Is this change going to be backward compatible?
Absolutely! Backward-compatibility is non-negotiable and we do everything to assure that the existing applications and libraries continue working as-is, without any modification. This is a gradual, opt-in change.
Is this another Angular rewrite?
No! This is mostly an additive change with some deeper modifications to the change detection algorithm. We take backwards compatibility seriously, and validate all changes with both our own suite of comprehensive tests and against the tests of thousands of Google applications built with Angular.
Is Angular getting less opinionated?
It's true that recent (and upcoming) changes to Angular have introduced new ways of building Angular applications. Most notably this includes standalone components and now signals. We introduce these new approaches over time to evolve the framework based on community feedback and our own observations of Angular in the wild. Our commitment to maintaining backwards compatibility means that the ecosystem ends up supporting multiple ways of doing things.
The result isn't that Angular is less opinionated, but instead that the opinions change over time. Typically, the most recent features represent the way we think most Angular developers should build their apps. We will always clearly communicate the preferred approach and update documentation / tooling accordingly. At the same time, the old way of building will live on for backwards compatibility (following our support policy).
Why are you working on signals and not feature XYZ?
In any popular framework there are always more features requested than we have bandwidth to work on at any given point in time. We are always focusing on projects that are the most helpful and impactful given the long-term evolution and stability of Angular. Signals are one of those projects.
First of all, improved runtime performance and optional zone.js was on our public roadmap for quite some time. Signals allow us to tackle this item.
More importantly, reactivity is at the very heart of a model-driven UI framework. By rethinking change detection, we open doors to simplification and evolutions that were not possible before. Faster performance, better forms, improved state management, and streamlined authoring format are prominent examples.
By baking-in reactivity into the framework we introduce primitives that the community can build upon.
Having said all this, the work on reactivity does not stop the work on the other important framework improvements. As an example, Angular v16 introduces the improved hydration, required inputs and tons of other improvements. We will continue working on other roadmap items while the reactivity work is in progress!
Appendix: How Angular change detection works today
Angular was built on the idea of a declarative, model-driven UI. Your application state is the source of truth and the framework automatically updates the page based on model changes. You declaratively express the mapping of model to UI via an HTML-like template. To keep the page up-to-date, the framework must track model changes over time.
zone.js
Angular uses zone.js to track various events in a browser (ex. DOM events, network requests and timers). Zone.js tracks these events by monkey-patching (wrapping and patching a callback function at runtime) any API that might lead to an application model change. When such an event occurs, however, Angular does not have any information as to what specific changes have occurred, or even if there were any changes at all.
Upon receiving event notification from zone.js, Angular will read (pull) new model values and update UI based on diffing the previously seen model values.
This approach provides excellent developer experience for small and simple applications:
setState
or similar APIs)In practice, however, large applications often grow to see zone.js become a source of performance issues and developer-facing complexity. As the web platform continues to grow and evolve, it also represents a rising maintenance cost for the Angular team.
While zone.js provides the mechanism that tells Angular when to run change detection, the next section discusses what this change detection entails.
Global, top-down change detection
Angular's default strategy is to run change detection over the entire component tree to make sure that the DOM reflects the most up-to-date model. Because Angular has no information about which parts of the application state have actually changed, it must check everything. In practice, however, only a fraction of the entire application state changes and only a handful of components need to be re-rendered.
Unidirectional data flow
Angular's change detection was designed to refresh application state once. The change detection process starts from the root of the component tree and walks all components down to the leaf nodes.
A single refresh traversal is sufficient if and only if components don’t modify the state of any of their ancestors after they have been visited. Unfortunately, the framework provides several convenient APIs to mutate state exactly in this way mid-traversal.
The component tree matches the rendered DOM tree, which means that change detection traverses the application in rendering order. However, several common web interaction patterns roll up descendant node states into ancestor nodes (e.g. form validity is computed as a function of descendant control states). This leads to the most "popular" error in Angular -
ExpressionChangedAfterItHasBeenCheckedError
.OnPush
Angular developers can optionally configure change detection to only run on a subset of the component tree using the OnPush strategy. Components configured as OnPush and their descendants are checked for changes only under specific conditions:
@Input()s
changed as a result of a template bindingWhile the OnPush strategy can reduce some of the performance cost, this strategy is limited:
RxJS integration
You might notice that none of this overview includes RxJS. Angular does not internally use RxJS to propagate state or drive rendering in any way. Instead, Angular uses RxJS as a convenient data structure to express streams of events over time (such as for
EventEmitter
), completely disconnected from the change detection and rendering system.Beta Was this translation helpful? Give feedback.
All reactions