Skip to content

Commit f09c5a7

Browse files
atscottpkozlowski-opensource
authored andcommitted
feat(core): Add zoneless change detection provider as experimental (angular#55329)
This commit adds the zoneless change detection provider function to the public API surface as experimental. PR Close angular#55329
1 parent 785c3c1 commit f09c5a7

File tree

6 files changed

+48
-5
lines changed

6 files changed

+48
-5
lines changed

goldens/public-api/core/index.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1353,6 +1353,9 @@ export class PlatformRef {
13531353
// @public
13541354
export type Predicate<T> = (value: T) => boolean;
13551355

1356+
// @public
1357+
export function provideExperimentalZonelessChangeDetection(): EnvironmentProviders;
1358+
13561359
// @public
13571360
export type Provider = TypeProvider | ValueProvider | ClassProvider | ConstructorProvider | ExistingProvider | FactoryProvider | any[];
13581361

packages/core/src/change_detection/scheduling/zoneless_scheduling_impl.ts

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,47 @@ export class ChangeDetectionSchedulerImpl implements ChangeDetectionScheduler {
142142
}
143143
}
144144

145-
export function provideZonelessChangeDetection(): EnvironmentProviders {
145+
146+
/**
147+
* Provides change detection without ZoneJS for the application bootstrapped using
148+
* `bootstrapApplication`.
149+
*
150+
* This function allows you to configure the application to not use the state/state changes of
151+
* ZoneJS to schedule change detection in the application. This will work when ZoneJS is not present
152+
* on the page at all or if it exists because something else is using it (either another Angular
153+
* application which uses ZoneJS for scheduling or some other library that relies on ZoneJS).
154+
*
155+
* This can also be added to the `TestBed` providers to configure the test environment to more
156+
* closely match production behavior. This will help give higher confidence that components are
157+
* compatible with zoneless change detection.
158+
*
159+
* ZoneJS uses browser events to trigger change detection. When using this provider, Angular will
160+
* instead use Angular APIs to schedule change detection. These APIs include:
161+
*
162+
* - `ChangeDetectorRef.markForCheck`
163+
* - `ComponentRef.setInput`
164+
* - updating a signal that is read in a template
165+
* - when bound host or template listeners are triggered
166+
* - attaching a view that was marked dirty by one of the above
167+
* - removing a view
168+
* - registering a render hook (templates are only refreshed if render hooks do one of the above)
169+
*
170+
* @usageNotes
171+
* ```typescript
172+
* bootstrapApplication(MyApp, {providers: [
173+
* provideExperimentalZonelessChangeDetection(),
174+
* ]});
175+
* ```
176+
*
177+
* This API is experimental. Neither the shape, nor the underlying behavior is stable and can change
178+
* in patch versions. There are known feature gaps, including the lack of a public zoneless API
179+
* which prevents the application from serializing too early with SSR.
180+
*
181+
* @publicApi
182+
* @experimental
183+
* @see {@link bootstrapApplication}
184+
*/
185+
export function provideExperimentalZonelessChangeDetection(): EnvironmentProviders {
146186
performanceMarkFeature('NgZoneless');
147187
return makeEnvironmentProviders([
148188
{provide: ChangeDetectionScheduler, useExisting: ChangeDetectionSchedulerImpl},

packages/core/src/core.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ export {BootstrapOptions, ApplicationRef, NgProbeToken, APP_BOOTSTRAP_LISTENER}
2828
export {PlatformRef} from './platform/platform_ref';
2929
export {createPlatform, createPlatformFactory, assertPlatform, destroyPlatform, getPlatform} from './platform/platform';
3030
export {provideZoneChangeDetection, NgZoneOptions} from './change_detection/scheduling/ng_zone_scheduling';
31+
export {provideExperimentalZonelessChangeDetection} from './change_detection/scheduling/zoneless_scheduling_impl';
3132
export {enableProdMode, isDevMode} from './util/is_dev_mode';
3233
export {APP_ID, PACKAGE_ROOT_URL, PLATFORM_INITIALIZER, PLATFORM_ID, ANIMATION_MODULE_TYPE, CSP_NONCE} from './application/application_tokens';
3334
export {APP_INITIALIZER, ApplicationInitStatus} from './application/application_init';

packages/core/src/core_private_export.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ export {IMAGE_CONFIG as ɵIMAGE_CONFIG, IMAGE_CONFIG_DEFAULTS as ɵIMAGE_CONFIG_
1212
export {internalCreateApplication as ɵinternalCreateApplication} from './application/create_application';
1313
export {defaultIterableDiffers as ɵdefaultIterableDiffers, defaultKeyValueDiffers as ɵdefaultKeyValueDiffers} from './change_detection/change_detection';
1414
export {ChangeDetectionScheduler as ɵChangeDetectionScheduler, ZONELESS_ENABLED as ɵZONELESS_ENABLED} from './change_detection/scheduling/zoneless_scheduling';
15-
export {provideZonelessChangeDetection as ɵprovideZonelessChangeDetection} from './change_detection/scheduling/zoneless_scheduling_impl';
1615
export {Console as ɵConsole} from './console';
1716
export {DeferBlockDetails as ɵDeferBlockDetails, getDeferBlocks as ɵgetDeferBlocks} from './defer/discovery';
1817
export {renderDeferBlockState as ɵrenderDeferBlockState, triggerResourceLoading as ɵtriggerResourceLoading} from './defer/instructions';

packages/core/test/change_detection_scheduler_spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
import {AsyncPipe} from '@angular/common';
1010
import {PLATFORM_BROWSER_ID} from '@angular/common/src/platform_id';
11-
import {afterNextRender, afterRender, ApplicationRef, ChangeDetectorRef, Component, createComponent, destroyPlatform, ElementRef, EnvironmentInjector, ErrorHandler, inject, Input, NgZone, PLATFORM_ID, provideZoneChangeDetection, signal, TemplateRef, Type, ViewChild, ViewContainerRef, ɵprovideZonelessChangeDetection as provideZonelessChangeDetection} from '@angular/core';
11+
import {afterNextRender, afterRender, ApplicationRef, ChangeDetectorRef, Component, createComponent, destroyPlatform, ElementRef, EnvironmentInjector, ErrorHandler, inject, Input, NgZone, PLATFORM_ID, provideExperimentalZonelessChangeDetection as provideZonelessChangeDetection, provideZoneChangeDetection, signal, TemplateRef, Type, ViewChild, ViewContainerRef} from '@angular/core';
1212
import {toSignal} from '@angular/core/rxjs-interop';
1313
import {ComponentFixture, ComponentFixtureAutoDetect, TestBed} from '@angular/core/testing';
1414
import {bootstrapApplication} from '@angular/platform-browser';

packages/core/test/component_fixture_spec.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
* found in the LICENSE file at https://angular.io/license
77
*/
88

9-
import {Component, Injectable, Input, signal, ɵprovideZonelessChangeDetection} from '@angular/core';
9+
import {Component, Injectable, Input, provideExperimentalZonelessChangeDetection, signal} from '@angular/core';
1010
import {ComponentFixtureAutoDetect, ComponentFixtureNoNgZone, TestBed, waitForAsync, withModule} from '@angular/core/testing';
1111
import {dispatchEvent} from '@angular/platform-browser/testing/src/browser_util';
1212
import {expect} from '@angular/platform-browser/testing/src/matchers';
@@ -373,7 +373,7 @@ describe('ComponentFixture with zoneless', () => {
373373
it('will not refresh CheckAlways views when detectChanges is called if not marked dirty', () => {
374374
TestBed.configureTestingModule({
375375
providers: [
376-
ɵprovideZonelessChangeDetection(),
376+
provideExperimentalZonelessChangeDetection(),
377377
{provide: AllowDetectChangesAndAcknowledgeItCanHideApplicationBugs, useValue: true},
378378
]
379379
});

0 commit comments

Comments
 (0)