Skip to content

Commit 0f0564b

Browse files
crisbetoannieyw
authored andcommitted
perf(cdk/a11y): only check for high contrast mode once (#22561)
I noticed this in the profiler while working on angular/material.angular.io#961. The `_applyBodyHighContrastModeCssClasses` method is called in the constructor of the `A11yModule` and `MatCommonModule` which means that it'll be invoked whenever a new root injector is created for a module importing any Material module (e.g. lazy-loaded route or dynamically-created component). Since it calls into `getHighContrastMode` and it touches the class list of `document.body`, it has the potential of causing some some slow layouts. This can be observed either when switching pages in the dev app or by profiling the example creation on material.angular.io. These changes resolve the issue by ensuring that we only run the logic once. (cherry picked from commit a92ad3d)
1 parent aae0fec commit 0f0564b

File tree

1 file changed

+7
-1
lines changed

1 file changed

+7
-1
lines changed

src/cdk/a11y/high-contrast-mode/high-contrast-mode-detector.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,11 @@ export const HIGH_CONTRAST_MODE_ACTIVE_CSS_CLASS = 'cdk-high-contrast-active';
4040
*/
4141
@Injectable({providedIn: 'root'})
4242
export class HighContrastModeDetector {
43+
/**
44+
* Figuring out the high contrast mode and adding the body classes can cause
45+
* some expensive layouts. This flag is used to ensure that we only do it once.
46+
*/
47+
private _hasCheckedHighContrastMode: boolean;
4348
private _document: Document;
4449

4550
constructor(private _platform: Platform, @Inject(DOCUMENT) document: any) {
@@ -80,12 +85,13 @@ export class HighContrastModeDetector {
8085

8186
/** Applies CSS classes indicating high-contrast mode to document body (browser-only). */
8287
_applyBodyHighContrastModeCssClasses(): void {
83-
if (this._platform.isBrowser && this._document.body) {
88+
if (!this._hasCheckedHighContrastMode && this._platform.isBrowser && this._document.body) {
8489
const bodyClasses = this._document.body.classList;
8590
// IE11 doesn't support `classList` operations with multiple arguments
8691
bodyClasses.remove(HIGH_CONTRAST_MODE_ACTIVE_CSS_CLASS);
8792
bodyClasses.remove(BLACK_ON_WHITE_CSS_CLASS);
8893
bodyClasses.remove(WHITE_ON_BLACK_CSS_CLASS);
94+
this._hasCheckedHighContrastMode = true;
8995

9096
const mode = this.getHighContrastMode();
9197
if (mode === HighContrastMode.BLACK_ON_WHITE) {

0 commit comments

Comments
 (0)