Skip to content

Commit a02075f

Browse files
committed
refactor(live-announcer): run outside NgZone
Switches to running the timeout from the `LiveAnnouncer` outside the `NgZone`, because it does all of its DOM manipulation directly on the element and it doesn't have to trigger Angular's change detection.
1 parent 877de56 commit a02075f

File tree

1 file changed

+13
-9
lines changed

1 file changed

+13
-9
lines changed

src/cdk/a11y/live-announcer/live-announcer.ts

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,8 @@ export class LiveAnnouncer implements OnDestroy {
3333

3434
constructor(
3535
@Optional() @Inject(LIVE_ANNOUNCER_ELEMENT_TOKEN) elementToken: any,
36-
@Inject(DOCUMENT) private _document: any) {
36+
@Inject(DOCUMENT) private _document: any,
37+
private _ngZone: NgZone) {
3738

3839
// We inject the live element and document as `any` because the constructor signature cannot
3940
// reference browser globals (HTMLElement, Document) on non-browser environments, since having
@@ -58,11 +59,13 @@ export class LiveAnnouncer implements OnDestroy {
5859
// - With Chrome and IE11 with NVDA or JAWS, a repeated (identical) message won't be read a
5960
// second time without clearing and then using a non-zero delay.
6061
// (using JAWS 17 at time of this writing).
61-
return new Promise(resolve => {
62-
setTimeout(() => {
63-
this._liveElement.textContent = message;
64-
resolve();
65-
}, 100);
62+
return this._ngZone.runOutsideAngular(() => {
63+
return new Promise(resolve => {
64+
setTimeout(() => {
65+
this._liveElement.textContent = message;
66+
resolve();
67+
}, 100);
68+
});
6669
});
6770
}
6871

@@ -73,7 +76,7 @@ export class LiveAnnouncer implements OnDestroy {
7376
}
7477

7578
private _createLiveElement(): HTMLElement {
76-
let liveEl = this._document.createElement('div');
79+
const liveEl = this._document.createElement('div');
7780

7881
liveEl.classList.add('cdk-live-announcer-element');
7982
liveEl.classList.add('cdk-visually-hidden');
@@ -134,8 +137,8 @@ export class CdkAriaLive implements OnDestroy {
134137

135138
/** @docs-private @deprecated @breaking-change 7.0.0 */
136139
export function LIVE_ANNOUNCER_PROVIDER_FACTORY(
137-
parentDispatcher: LiveAnnouncer, liveElement: any, _document: any) {
138-
return parentDispatcher || new LiveAnnouncer(liveElement, _document);
140+
parentDispatcher: LiveAnnouncer, liveElement: any, _document: any, ngZone: NgZone) {
141+
return parentDispatcher || new LiveAnnouncer(liveElement, _document, ngZone);
139142
}
140143

141144

@@ -147,6 +150,7 @@ export const LIVE_ANNOUNCER_PROVIDER: Provider = {
147150
[new Optional(), new SkipSelf(), LiveAnnouncer],
148151
[new Optional(), new Inject(LIVE_ANNOUNCER_ELEMENT_TOKEN)],
149152
DOCUMENT,
153+
NgZone,
150154
],
151155
useFactory: LIVE_ANNOUNCER_PROVIDER_FACTORY
152156
};

0 commit comments

Comments
 (0)