Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 953c4b2

Browse files
atscottpkozlowski-opensource
authored andcommitted
feat(core): Move zoneless change detection to dev preview (#60748)
This commit moves zoneless from experimental to developer preview. * Update tag on provider API * Remove "experimental" from provider name * Move documentation from "experimental features" to "Best practives -> Performance" (at least temporarily until there is a better place) BREAKING CHANGE: `provideExperimentalZonelessChangeDetection` is renamed to `provideZonelessChangeDetection` as it is now "Developer Preview" rather than "Experimental". PR Close #60748
1 parent 550a63b commit 953c4b2

34 files changed

+80
-90
lines changed

‎adev/shared-docs/components/breadcrumb/breadcrumb.component.spec.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import {NavigationState} from '../../services';
1313
import {NavigationItem} from '../../interfaces';
1414
import {By} from '@angular/platform-browser';
1515
import {RouterTestingModule} from '@angular/router/testing';
16-
import {provideExperimentalZonelessChangeDetection} from '@angular/core';
16+
import {provideZonelessChangeDetection} from '@angular/core';
1717

1818
describe('Breadcrumb', () => {
1919
let fixture: ComponentFixture<Breadcrumb>;
@@ -25,7 +25,7 @@ describe('Breadcrumb', () => {
2525
TestBed.configureTestingModule({
2626
imports: [Breadcrumb, RouterTestingModule],
2727
providers: [
28-
provideExperimentalZonelessChangeDetection(),
28+
provideZonelessChangeDetection(),
2929
{
3030
provide: NavigationState,
3131
useValue: navigationStateSpy,

‎adev/shared-docs/components/cookie-popup/cookie-popup.component.spec.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import {ComponentFixture, TestBed} from '@angular/core/testing';
1111
import {CookiePopup, STORAGE_KEY} from './cookie-popup.component';
1212
import {LOCAL_STORAGE} from '../../providers/index';
1313
import {MockLocalStorage} from '../../testing/index';
14-
import {provideExperimentalZonelessChangeDetection} from '@angular/core';
14+
import {provideZonelessChangeDetection} from '@angular/core';
1515

1616
describe('CookiePopup', () => {
1717
let fixture: ComponentFixture<CookiePopup>;
@@ -21,7 +21,7 @@ describe('CookiePopup', () => {
2121
TestBed.configureTestingModule({
2222
imports: [CookiePopup],
2323
providers: [
24-
provideExperimentalZonelessChangeDetection(),
24+
provideZonelessChangeDetection(),
2525
{
2626
provide: LOCAL_STORAGE,
2727
useValue: mockLocalStorage,

‎adev/shared-docs/components/copy-source-code-button/copy-source-code-button.component.spec.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import {
1515
import {
1616
ChangeDetectionStrategy,
1717
Component,
18-
provideExperimentalZonelessChangeDetection,
18+
provideZonelessChangeDetection,
1919
signal,
2020
} from '@angular/core';
2121
import {By} from '@angular/platform-browser';
@@ -32,7 +32,7 @@ describe('CopySourceCodeButton', () => {
3232
beforeEach(async () => {
3333
TestBed.configureTestingModule({
3434
imports: [CodeSnippetWrapper],
35-
providers: [provideExperimentalZonelessChangeDetection()],
35+
providers: [provideZonelessChangeDetection()],
3636
});
3737
fixture = TestBed.createComponent(CodeSnippetWrapper);
3838
component = fixture.componentInstance;

‎adev/shared-docs/components/navigation-list/navigation-list.component.spec.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import {NavigationList} from './navigation-list.component';
1212
import {By} from '@angular/platform-browser';
1313
import {NavigationItem} from '../../interfaces';
1414
import {provideRouter} from '@angular/router';
15-
import {provideExperimentalZonelessChangeDetection, signal} from '@angular/core';
15+
import {provideZonelessChangeDetection, signal} from '@angular/core';
1616
import {NavigationState} from '../../services';
1717

1818
const navigationItems: NavigationItem[] = [
@@ -41,7 +41,7 @@ describe('NavigationList', () => {
4141
providers: [
4242
provideRouter([]),
4343
{provide: NavigationState, useClass: FakeNavigationListState},
44-
provideExperimentalZonelessChangeDetection(),
44+
provideZonelessChangeDetection(),
4545
],
4646
}).compileComponents();
4747
fixture = TestBed.createComponent(NavigationList);

‎adev/shared-docs/components/search-dialog/search-dialog.component.spec.ts

+2-6
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,7 @@ import {By} from '@angular/platform-browser';
1616
import {AlgoliaIcon} from '../algolia-icon/algolia-icon.component';
1717
import {RouterTestingModule} from '@angular/router/testing';
1818
import {Router} from '@angular/router';
19-
import {
20-
ApplicationRef,
21-
provideExperimentalZonelessChangeDetection,
22-
ResourceStatus,
23-
} from '@angular/core';
19+
import {ApplicationRef, provideZonelessChangeDetection, ResourceStatus} from '@angular/core';
2420
import {SearchResult} from '../../interfaces';
2521

2622
describe('SearchDialog', () => {
@@ -38,7 +34,7 @@ describe('SearchDialog', () => {
3834
TestBed.configureTestingModule({
3935
imports: [SearchDialog, RouterTestingModule],
4036
providers: [
41-
provideExperimentalZonelessChangeDetection(),
37+
provideZonelessChangeDetection(),
4238
{provide: ENVIRONMENT, useValue: {algolia: {index: 'fakeIndex'}}},
4339
{provide: ALGOLIA_CLIENT, useValue: {search: searchResults}},
4440
{provide: WINDOW, useValue: fakeWindow},

‎adev/shared-docs/components/select/select.component.spec.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
import {ComponentFixture, TestBed} from '@angular/core/testing';
1010

1111
import {Select} from './select.component';
12-
import {provideExperimentalZonelessChangeDetection} from '@angular/core';
12+
import {provideZonelessChangeDetection} from '@angular/core';
1313

1414
describe('Select', () => {
1515
let component: Select;
@@ -18,7 +18,7 @@ describe('Select', () => {
1818
beforeEach(() => {
1919
TestBed.configureTestingModule({
2020
imports: [Select],
21-
providers: [provideExperimentalZonelessChangeDetection()],
21+
providers: [provideZonelessChangeDetection()],
2222
});
2323
fixture = TestBed.createComponent(Select);
2424
component = fixture.componentInstance;

‎adev/shared-docs/components/slide-toggle/slide-toggle.component.spec.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
import {ComponentFixture, TestBed} from '@angular/core/testing';
1010

1111
import {SlideToggle} from './slide-toggle.component';
12-
import {provideExperimentalZonelessChangeDetection} from '@angular/core';
12+
import {provideZonelessChangeDetection} from '@angular/core';
1313

1414
describe('SlideToggle', () => {
1515
let component: SlideToggle;
@@ -18,7 +18,7 @@ describe('SlideToggle', () => {
1818
beforeEach(() => {
1919
TestBed.configureTestingModule({
2020
imports: [SlideToggle],
21-
providers: [provideExperimentalZonelessChangeDetection()],
21+
providers: [provideZonelessChangeDetection()],
2222
});
2323
fixture = TestBed.createComponent(SlideToggle);
2424
fixture.componentRef.setInput('buttonId', 'id');

‎adev/shared-docs/components/table-of-contents/table-of-contents.component.spec.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import {RouterTestingModule} from '@angular/router/testing';
1212
import {TableOfContentsItem, TableOfContentsLevel} from '../../interfaces/index';
1313
import {TableOfContentsLoader} from '../../services/index';
1414
import {WINDOW} from '../../providers/index';
15-
import {provideExperimentalZonelessChangeDetection, signal} from '@angular/core';
15+
import {provideZonelessChangeDetection, signal} from '@angular/core';
1616

1717
describe('TableOfContents', () => {
1818
let component: TableOfContents;
@@ -43,7 +43,7 @@ describe('TableOfContents', () => {
4343
await TestBed.configureTestingModule({
4444
imports: [TableOfContents, RouterTestingModule],
4545
providers: [
46-
provideExperimentalZonelessChangeDetection(),
46+
provideZonelessChangeDetection(),
4747
{
4848
provide: WINDOW,
4949
useValue: fakeWindow,

‎adev/shared-docs/components/text-field/text-field.component.spec.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
import {ComponentFixture, TestBed} from '@angular/core/testing';
1010

1111
import {TextField} from './text-field.component';
12-
import {provideExperimentalZonelessChangeDetection} from '@angular/core';
12+
import {provideZonelessChangeDetection} from '@angular/core';
1313

1414
describe('TextField', () => {
1515
let component: TextField;
@@ -18,7 +18,7 @@ describe('TextField', () => {
1818
beforeEach(() => {
1919
TestBed.configureTestingModule({
2020
imports: [TextField],
21-
providers: [provideExperimentalZonelessChangeDetection()],
21+
providers: [provideZonelessChangeDetection()],
2222
});
2323
fixture = TestBed.createComponent(TextField);
2424
component = fixture.componentInstance;

‎adev/shared-docs/components/viewers/docs-viewer/docs-viewer.component.spec.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ import {Breadcrumb} from '../../breadcrumb/breadcrumb.component';
1818
import {NavigationState} from '../../../services';
1919
import {CopySourceCodeButton} from '../../copy-source-code-button/copy-source-code-button.component';
2020
import {TableOfContents} from '../../table-of-contents/table-of-contents.component';
21-
import {provideExperimentalZonelessChangeDetection} from '@angular/core';
21+
import {provideZonelessChangeDetection} from '@angular/core';
2222

2323
describe('DocViewer', () => {
2424
let fixture: ComponentFixture<DocViewer>;
@@ -82,7 +82,7 @@ describe('DocViewer', () => {
8282
imports: [DocViewer],
8383
providers: [
8484
provideRouter([]),
85-
provideExperimentalZonelessChangeDetection(),
85+
provideZonelessChangeDetection(),
8686
{provide: EXAMPLE_VIEWER_CONTENT_LOADER, useValue: exampleContentSpy},
8787
{provide: NavigationState, useValue: navigationStateSpy},
8888
],

‎adev/shared-docs/components/viewers/example-viewer/example-viewer.component.spec.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import {ComponentFixture, TestBed, waitForAsync} from '@angular/core/testing';
1010
import {ExampleViewer} from './example-viewer.component';
1111
import {ExampleMetadata, ExampleViewerContentLoader} from '../../../interfaces';
1212
import {EXAMPLE_VIEWER_CONTENT_LOADER} from '../../../providers';
13-
import {Component, provideExperimentalZonelessChangeDetection, ComponentRef} from '@angular/core';
13+
import {Component, provideZonelessChangeDetection, ComponentRef} from '@angular/core';
1414
import {HarnessLoader} from '@angular/cdk/testing';
1515
import {TestbedHarnessEnvironment} from '@angular/cdk/testing/testbed';
1616
import {Clipboard} from '@angular/cdk/clipboard';
@@ -36,7 +36,7 @@ describe('ExampleViewer', () => {
3636
imports: [ExampleViewer],
3737
providers: [
3838
// TODO: Find why tests warn that zone.js is still loaded
39-
provideExperimentalZonelessChangeDetection(),
39+
provideZonelessChangeDetection(),
4040
{provide: EXAMPLE_VIEWER_CONTENT_LOADER, useValue: exampleContentSpy},
4141
{provide: ActivatedRoute, useValue: {snapshot: {fragment: 'fragment'}}},
4242
],

‎adev/src/app/app.config.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import {
1313
ErrorHandler,
1414
VERSION,
1515
inject,
16-
provideExperimentalZonelessChangeDetection,
16+
provideZonelessChangeDetection,
1717
provideEnvironmentInitializer,
1818
} from '@angular/core';
1919
import {
@@ -38,7 +38,7 @@ import {routerProviders} from './router_providers';
3838
export const appConfig: ApplicationConfig = {
3939
providers: [
4040
routerProviders,
41-
provideExperimentalZonelessChangeDetection(),
41+
provideZonelessChangeDetection(),
4242
provideClientHydration(),
4343
provideHttpClient(withFetch()),
4444
provideEnvironmentInitializer(() => inject(AnalyticsService)),

‎adev/src/app/sub-navigation-data.ts

+1-6
Original file line numberDiff line numberDiff line change
@@ -583,12 +583,6 @@ const DOCS_SUB_NAVIGATION_DATA: NavigationItem[] = [
583583
},
584584
],
585585
},
586-
{
587-
label: 'Experimental features',
588-
children: [
589-
{label: 'Zoneless', path: 'guide/experimental/zoneless', contentPath: 'guide/zoneless'},
590-
],
591-
},
592586
],
593587
},
594588
{
@@ -752,6 +746,7 @@ const DOCS_SUB_NAVIGATION_DATA: NavigationItem[] = [
752746
path: 'best-practices/skipping-subtrees',
753747
contentPath: 'best-practices/runtime-performance/skipping-subtrees',
754748
},
749+
{label: 'Zoneless', path: 'guide/zoneless', contentPath: 'guide/zoneless'},
755750
],
756751
},
757752
{

‎adev/src/content/guide/testing/components-scenarios.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ Then add it to the `providers` array of the testing module configuration:
7373

7474
HELPFUL: You can also use the `fixture.autoDetectChanges()` function instead if you only want to enable automatic change detection
7575
after making updates to the state of the fixture's component. In addition, automatic change detection is on by default
76-
when using `provideExperimentalZonelessChangeDetection` and turning it off is not recommended.
76+
when using `provideZonelessChangeDetection` and turning it off is not recommended.
7777

7878
Here are three tests that illustrate how automatic change detection works.
7979

‎adev/src/content/guide/zoneless.md

+4-5
Original file line numberDiff line numberDiff line change
@@ -11,19 +11,18 @@ The main advantages to removing ZoneJS as a dependency are:
1111

1212
## Enabling Zoneless in an application
1313

14-
The API for enabling Zoneless is currently experimental. Neither the shape, nor the underlying behavior is stable and can change
15-
in patch versions. There are known feature gaps, including the lack of an ergonomic API which prevents the application from serializing too early with Server Side Rendering.
14+
The API for enabling Zoneless is currently in developer preview. The shape of the API and underlying behavior can change in patch versions.
1615

1716
```typescript
1817
// standalone bootstrap
1918
bootstrapApplication(MyApp, {providers: [
20-
provideExperimentalZonelessChangeDetection(),
19+
provideZonelessChangeDetection(),
2120
]});
2221

2322
// NgModule bootstrap
2423
platformBrowser().bootstrapModule(AppModule);
2524
@NgModule({
26-
providers: [provideExperimentalZonelessChangeDetection()]
25+
providers: [provideZonelessChangeDetection()]
2726
})
2827
export class AppModule {}
2928
```
@@ -134,7 +133,7 @@ Angular application.
134133

135134
```typescript
136135
TestBed.configureTestingModule({
137-
providers: [provideExperimentalZonelessChangeDetection()]
136+
providers: [provideZonelessChangeDetection()]
138137
});
139138

140139
const fixture = TestBed.createComponent(MyComponent);

‎adev/src/content/reference/roadmap.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ Start developing with the latest Angular features from our roadmap. This list re
2020
### Available to experiment with
2121

2222
* [Incremental hydration](/guide/incremental-hydration)
23-
* [Zoneless change detection](/guide/experimental/zoneless)
23+
* [Zoneless change detection](/guide/zoneless)
2424
* [Hydration support for i18n blocks](/api/platform-browser/withI18nSupport)
2525
* [Resource API](/guide/signals/resource)
2626
* [Effect API](/api/core/effect)

‎adev/test-main.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,13 @@
66
* found in the LICENSE file at https://angular.dev/license
77
*/
88

9-
import {ErrorHandler, NgModule, provideExperimentalZonelessChangeDetection} from '@angular/core';
9+
import {ErrorHandler, NgModule, provideZonelessChangeDetection} from '@angular/core';
1010
import {TestBed} from '@angular/core/testing';
1111
import {BrowserTestingModule, platformBrowserTesting} from '@angular/platform-browser/testing';
1212

1313
@NgModule({
1414
providers: [
15-
provideExperimentalZonelessChangeDetection(),
15+
provideZonelessChangeDetection(),
1616
{
1717
provide: ErrorHandler,
1818
useValue: {

‎goldens/public-api/core/index.api.md

+5-3
Original file line numberDiff line numberDiff line change
@@ -1459,9 +1459,6 @@ export function provideExperimentalCheckNoChangesForDebug(options: {
14591459
exhaustive?: boolean;
14601460
}): _angular_core.EnvironmentProviders;
14611461

1462-
// @public
1463-
export function provideExperimentalZonelessChangeDetection(): EnvironmentProviders;
1464-
14651462
// @public
14661463
export function providePlatformInitializer(initializerFn: () => void): EnvironmentProviders;
14671464

@@ -1474,6 +1471,11 @@ export type ProviderToken<T> = Type<T> | AbstractType<T> | InjectionToken<T>;
14741471
// @public
14751472
export function provideZoneChangeDetection(options?: NgZoneOptions): EnvironmentProviders;
14761473

1474+
// @public
1475+
function provideZonelessChangeDetection(): EnvironmentProviders;
1476+
export { provideZonelessChangeDetection as provideExperimentalZonelessChangeDetection }
1477+
export { provideZonelessChangeDetection }
1478+
14771479
// @public
14781480
export interface Query {
14791481
// (undocumented)

‎modules/ssr-benchmarks/src/app/app.config.ts

+2-5
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,10 @@
66
* found in the LICENSE file at https://angular.dev/license
77
*/
88

9-
import {ApplicationConfig, provideExperimentalZonelessChangeDetection} from '@angular/core';
9+
import {ApplicationConfig, provideZonelessChangeDetection} from '@angular/core';
1010

1111
import {provideClientHydration, withEventReplay} from '@angular/platform-browser';
1212

1313
export const appConfig: ApplicationConfig = {
14-
providers: [
15-
provideExperimentalZonelessChangeDetection(),
16-
provideClientHydration(withEventReplay()),
17-
],
14+
providers: [provideZonelessChangeDetection(), provideClientHydration(withEventReplay())],
1815
};

‎packages/core/src/change_detection/scheduling/exhaustive_check_no_changes.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ import {ZONELESS_ENABLED} from './zoneless_scheduling';
3434
* and will always check all views, regardless of their "dirty" state and `ChangeDetectionStrategy`.
3535
*
3636
* When the `useNgZoneOnStable` option is `true`, this function will provide its own `NgZone` implementation and needs
37-
* to come after any other `NgZone` provider, including `provideZoneChangeDetection()` and `provideExperimentalZonelessChangeDetection()`.
37+
* to come after any other `NgZone` provider, including `provideZoneChangeDetection()` and `provideZonelessChangeDetection()`.
3838
*
3939
* @experimental
4040
* @publicApi

‎packages/core/src/change_detection/scheduling/zoneless_scheduling.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ export const ZONELESS_ENABLED = new InjectionToken<boolean>(
6969
{providedIn: 'root', factory: () => false},
7070
);
7171

72-
/** Token used to indicate `provideExperimentalZonelessChangeDetection` was used. */
72+
/** Token used to indicate `provideZonelessChangeDetection` was used. */
7373
export const PROVIDED_ZONELESS = new InjectionToken<boolean>(
7474
typeof ngDevMode === 'undefined' || ngDevMode ? 'Zoneless provided' : '',
7575
{providedIn: 'root', factory: () => false},

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

+3-3
Original file line numberDiff line numberDiff line change
@@ -361,7 +361,7 @@ export class ChangeDetectionSchedulerImpl implements ChangeDetectionScheduler {
361361
* @usageNotes
362362
* ```ts
363363
* bootstrapApplication(MyApp, {providers: [
364-
* provideExperimentalZonelessChangeDetection(),
364+
* provideZonelessChangeDetection(),
365365
* ]});
366366
* ```
367367
*
@@ -370,10 +370,10 @@ export class ChangeDetectionSchedulerImpl implements ChangeDetectionScheduler {
370370
* on the exact API based on the feedback and our understanding of the problem and solution space.
371371
*
372372
* @publicApi
373-
* @experimental
373+
* @developerPreview
374374
* @see {@link /api/platform-browser/bootstrapApplication bootstrapApplication}
375375
*/
376-
export function provideExperimentalZonelessChangeDetection(): EnvironmentProviders {
376+
export function provideZonelessChangeDetection(): EnvironmentProviders {
377377
performanceMarkFeature('NgZoneless');
378378

379379
if ((typeof ngDevMode === 'undefined' || ngDevMode) && typeof Zone !== 'undefined' && Zone) {

‎packages/core/src/core.ts

+5-1
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,11 @@ export {
4343
provideZoneChangeDetection,
4444
NgZoneOptions,
4545
} from './change_detection/scheduling/ng_zone_scheduling';
46-
export {provideExperimentalZonelessChangeDetection} from './change_detection/scheduling/zoneless_scheduling_impl';
46+
export {
47+
provideZonelessChangeDetection,
48+
// TODO(atscott): Remove after internal LSC for name change
49+
provideZonelessChangeDetection as provideExperimentalZonelessChangeDetection,
50+
} from './change_detection/scheduling/zoneless_scheduling_impl';
4751
export {PendingTasks} from './pending_tasks';
4852
export {provideExperimentalCheckNoChangesForDebug} from './change_detection/scheduling/exhaustive_check_no_changes';
4953
export {enableProdMode, isDevMode} from './util/is_dev_mode';

0 commit comments

Comments
 (0)