Skip to content

Commit 7755aa5

Browse files
committed
perf(material/chips): reduce amount of macro tasks (#26113)
* Fixes that the chip grid was triggering a bunch of change detections on initialization through a `setTimeout` inside `setDescribedByIds`. * Replaces most of the remaining timeouts in the chips with `Promise.resolve`. Fixes #25325. (cherry picked from commit 33db089)
1 parent 1566ab1 commit 7755aa5

File tree

4 files changed

+11
-16
lines changed

4 files changed

+11
-16
lines changed

src/material/chips/chip-grid.ts

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -363,15 +363,7 @@ export class MatChipGrid
363363
// We must keep this up to date to handle the case where ids are set
364364
// before the chip input is registered.
365365
this._ariaDescribedbyIds = ids;
366-
367-
if (this._chipInput) {
368-
// Use a setTimeout in case this is being run during change detection
369-
// and the chip input has already determined its host binding for
370-
// aria-describedBy.
371-
setTimeout(() => {
372-
this._chipInput.setDescribedByIds(ids);
373-
}, 0);
374-
}
366+
this._chipInput?.setDescribedByIds(ids);
375367
}
376368

377369
/**

src/material/chips/chip-input.ts

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,6 @@ let nextUniqueId = 0;
6565
'[attr.disabled]': 'disabled || null',
6666
'[attr.placeholder]': 'placeholder || null',
6767
'[attr.aria-invalid]': '_chipGrid && _chipGrid.ngControl ? _chipGrid.ngControl.invalid : null',
68-
'[attr.aria-describedby]': '_ariaDescribedby || null',
6968
'[attr.aria-required]': '_chipGrid && _chipGrid.required || null',
7069
'[attr.required]': '_chipGrid && _chipGrid.required || null',
7170
},
@@ -74,9 +73,6 @@ export class MatChipInput implements MatChipTextControl, AfterContentInit, OnCha
7473
/** Used to prevent focus moving to chips while user is holding backspace */
7574
private _focusLastChipOnBackspace: boolean;
7675

77-
/** Value for ariaDescribedby property */
78-
_ariaDescribedby?: string;
79-
8076
/** Whether the control is focused. */
8177
focused: boolean = false;
8278
_chipGrid: MatChipGrid;
@@ -241,7 +237,15 @@ export class MatChipInput implements MatChipTextControl, AfterContentInit, OnCha
241237
}
242238

243239
setDescribedByIds(ids: string[]): void {
244-
this._ariaDescribedby = ids.join(' ');
240+
const element = this._elementRef.nativeElement;
241+
242+
// Set the value directly in the DOM since this binding
243+
// is prone to "changed after checked" errors.
244+
if (ids.length) {
245+
element.setAttribute('aria-describedby', ids.join(' '));
246+
} else {
247+
element.removeAttribute('aria-describedby');
248+
}
245249
}
246250

247251
/** Checks whether a keycode is one of the configured separators. */

src/material/chips/chip-set.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,7 @@ export class MatChipSet
199199
if (this.tabIndex !== -1) {
200200
this.tabIndex = -1;
201201

202-
setTimeout(() => {
202+
Promise.resolve().then(() => {
203203
this.tabIndex = previousTabIndex;
204204
this._changeDetectorRef.markForCheck();
205205
});

tools/public_api_guard/material/chips.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -228,7 +228,6 @@ export class MatChipInput implements MatChipTextControl, AfterContentInit, OnCha
228228
set addOnBlur(value: BooleanInput);
229229
// (undocumented)
230230
_addOnBlur: boolean;
231-
_ariaDescribedby?: string;
232231
_blur(): void;
233232
readonly chipEnd: EventEmitter<MatChipInputEvent>;
234233
set chipGrid(value: MatChipGrid);

0 commit comments

Comments
 (0)