This commit updates `@defer` logic related to handling `after` and `minimum` parameters tree-shakable.
If `after` or `minimum` was used on a `@loading` or `@placeholder` blocks, compiler generates an extra argument for the `ɵɵdefer` instruction. This extra argument is a reference to a function that brings timer-related code.
PR Close#52042
The context of an embedded view ref at some point was switched from a
getter to an actual assignable property. This is something we reverted
with the previous commit as it introduces additional complexity for our
generated code (in terms of closures capturing the `ctx`).
This change impacted the template outlet code because we actively relied
on swapping out the full context if the user changes it. Previousl,
before we allowed to swap out the context (in v16), we mutated the
initial view context if it didn't change structurally- and in other
cases the view was re-created. We improved this performance aspect with
the changes to allow for the context to be swapped out + actually also
fixed a bug where the initial context object was mutated and the user
could observe this change.
This commit adjusts for context not being replacable- while still
keeping the bugs fixed and preserving the performance wins of not
having to destroy/re-create the view whenever the context changes.
Benchmarks: https://hackmd.io/J0Ci_JzxQ0K1AA1omXhIQQ
PR Close#51887
This integration test aims to cover that we do not break the code splitting of the animation module when we use `provideAnimationsAsync()`.
PR Close#50738
This commit refactors the router internals to track state inside a separate
`StateManager`. This helps open the door to managing the state in
different, swappable providers. The current interface needed by the
Router is: `currentUrlTree`, `rawUrlTree`, `browserUrlTree`,
`routerState`, and `handleNavigationEvent` (other properties are because
some router properties are writeable when they shouldn't be). This is
a suprisingly small interface and can hopefully be made smaller in the
future (i.e. removing 1 or more of the 3 tracked of `UrlTree`s).
PR Close#48481
This commit switches the signals library from a bidirectional symmetric
dependency graph using weak references, to a bidirectional _asymmetric_
graph which uses strong references. This is made possible with a reference
counting algorithm which only tracks producer -> consumer references for
effect-like "live" consumers, preventing memory leaks.
The new algorithm should be simpler and faster than the previous
implementation as weak references are fairly slow to create and traverse.
A tradeoff is that non-live consumers must now poll their producers when
read, as they cannot rely on dirty notifications.
As part of this refactoring, the `ReactiveNode` class is replaced with an
interface instead, and methods are moved to standalone functions. This is
paired with instantiating individual signals/computeds via `Object.create`
against a prototype node which contains static or initial values. This
technique, in conjunction with the rest, greatly improves the performance
of node creation.
PR Close#51226
Previously, with `mergeMap` we did not cancel previous subscriptions to zoneIsStable which caused the application to be stablized before hand.
Closes: #50562
PR Close#50573
This commit updates the `ApplicationRef.isStable` API to account for
pending rendering task. This is needed as once a pending rendering task
is done, new macrotask and microtask could be created which previously caused these not
to be intercepted and thus ignored when doing SSR.
PR Close#50425
The `main` bundle fell below the threshold. No actual investigation
was done here because it's a reduction in size, and the AIO size
matches the `AIO-local` size now. This is expected because the latest
RC closely matches the `main` branch (or even is equivalent at this
point).
PR Close#50107
In archive mode the link to the current doc will now point to same page.
If the page doesn't exist anymore, it will show a contextualized warning message.
See #46850
PR Close#49063
Previously the signals implementation maintained separate interfaces for
`Producer` and `Consumer` nodes, with implementers choosing to implement
one or both interfaces. Operations defined against those interfaces were
exposed as importable functions to be called with the object implementing
the relevant contract as the first argument.
This commit refactors the implementation to merge both abstractions into a
single `ReactiveNode` base class, which represents both producers and
consumers in the graph. Implementers choose to interact with a subset of the
`ReactiveNode` API depending on their role in the graph. Operations are now
available as protected methods on the base class, instead of separate
functions.
PR Close#49529
When navigating in the Router, the current approach does the redirects
and the creation of the `RouterStateSnapshot` in two separate steps
(applyRedirects and recognize). These two steps duplicate the route
matching logic, resulting in user code on routes being executing twice
(custom `UrlMatcher` and `canMatch` guards). This also duplicates the
complex matching logic in two places, which increases the bundle size
and maintenance burden.
This commit combines the `applyRedirects` and `recognize` steps into a
single matching algorithm.
fixes#26081
PR Close#49163
This commit updates the `LView` in Angular to be a `Consumer` of
signals. If a signal is read when executing a template, it marks the
view dirty. In addition, if a signal is read when executing host
bindings, it also marks views dirty.
One interesting thing about signal reads in host bindings
is that they perform a bit better than what we can do with today's
APIs. In order to re-execute host bindings for an `OnPush` component that
might have changed, you would probably inject `ChangeDetectorRef` and call
`markForCheck`. This will mark the _current component_ and parents
dirty. However, host bindings are executed as part of refreshing the
_parent_ so there is really no need to re-execute the current component
if the only thing that changed is the host bindings. When a signal is
read in host bindings, it marks the parent dirty and not the component
that defined the host binding.
Additionally, this commit avoids allocating a full consumer for each
`LView` by re-using a consumer until template execution results in a
signal read. At this point, we assign that consumer to the `LView` and
create a new consumer to "tentatively" use for the future `LView`
template executions.
Co-authored-by: Dylan Hunn <github@dylanhunn.com>
PR Close#49153
This change makes it possible to remove a previously registered destroy
callback - to do so it is enough to call the unregistration function
returned from the onDestroy method call.
PR Close#49493
The `i18n` integration size test golden has been updated with
an increase 20hrs ago, but now with the recent Angular update,
it seems back to the previous size, a decrease in size.
https://github.com/angular/angular/pull/49495.
PR Close#49514
This commit implements hydration support for view containers, which should make `*ngIf`, `*ngFor` and other structural directive work with hydration.
The logic also respects the `ngSkipHydration` flag and skips hydration in such cases.
PR Close#49382
This commit moves the providers for `NgZone`-based change detection to a
single provider function. This function is currently called by default
in all places where `NgZone` was provided
(`bootstrapApplication`, `bootstrapModule`, and `TestBed`).
When we want to make Angular applications zoneless by default, we
can make a public provider method that has to be used in order to enable
the zone change detection features. When this method is not called,
Angular would use `NoopNgZone` by default and not initialize any
subscriptions to the `NgZone` stability events.
Side note: There are actually two places that `NgZone` is provided for `TestBed`
(providers in `compileTestModule` and `BrowserTestingModule`). This
likely doesn't need to be in both locations.
PR Close#49373
Prior to this change component styles generated on the server where removed prior to the client side component being rendered and attached it's own styles. In some cases this caused flickering. To mitigate this `initialNavigation: enabledBlocking'` was introduced which allowed the remove of server styles to be defer to a latter stage when the application has finished initialization.
This commit changes the need for this, by not removing the server generated component styles and reuse them for client side rendering.
PR Close#48253
Prior to this change the component IDs where generated based on a counter. This is problematic as there is no guarantee that a component will get the same ID that was assigned on the server when generated on the client side.
This is paramount to be able to re-use the component styles generated on the server.
PR Close#48253
This adds the ngSkipHydration annotation, which allows users to
opt hydration boundaries out of hydration. This enables incremental
adoption of hydration by letting users skip hydration on components
that have implementation issues that conflict with hydration.
co-authored-by: AndrewKushnir <akushnir@google.com>
PR Close#49345
This commit incrementally builds on top of #49285 and adds the logic to hydrate <ng-container>s and their contents. This implementation supports simple <ng-container>s that don't have any Angular features (like *ngIf/*ngFor, etc) and are not content-projected.
The subsequent commits will extend the logic further to support more complex scenarios.
PR Close#49303
* With tsc improvements some types can be refined.
* Removing unnecessary non-null assertions.
* Using std native methods instand of custom functions
* Using @ts-expect-error instead of `any` type assertion to keep code navigation.
PR Close#49206
DestroyRef represents a concept of lifecycle scope where destroy
callbacks can be registered. Such callbacks are automatically
executed when a given scope ends it lifecycle.
In practice the most common lifecycle scopes would be represented by:
- a component or en embedded view;
- instance of `EnvironnementInjector`.
PR Close#49158
Currently style of components using `encapsulation`, `None` or `Emulated` will not be removed from the DOM once the component get destroyed.
This change addresses this by keeping track of the number of times a component is rendered, when the component is destroyed the counter is decreased and once this reaches zero the style element is removed from the DOM.
Currently, this new behaviour is on opt-in bases, but it will be changed in the next major version.
To opt-in, set the `REMOVE_STYLES_ON_COMPONENT_DESTROY` DI token to `true`.
Example
```ts
@NgModule({
declarations: [
AppComponent,
],
imports: [
BrowserModule
],
providers: [
{ provide: REMOVE_STYLES_ON_COMPONENT_DESTROY, useValue: true }
],
bootstrap: [AppComponent]
})
export class AppModule { }
```
Closes#16670
PR Close#48298
The Angular devkit updated Terser. Terser landed various changes
related to variable inlining. Most constants are no longer inlined,
but instead the variables are re-used.
This led to a bundle size increase of around ~600B in AIO and most
integration tests.
Here is an example diff:
https://screenshot.googleplex.com/4M8owBYDAqU982T
PR Close#48996
The main entry point for the `@angular/localize` package no longer imports
the `@angular/compiler` package and now has no external dependencies. This
allows the main functionality of the package to be used without requiring
any other Angular packages. Only the message digest algorithm implementation
from the `@angular/compiler` package was being used and this code is now
bundled directly into the final npm package for `@angular/localize`.
The `tooling` secondary entry point still leverages and requires Angular
related packages (`@angular/compiler`/`@angular/compiler-cli`). However,
the tooling functionality is not intended to be used and/or bundled in
a web application.
Closes#48163
PR Close#48799