Skip to content

Commit

Permalink
perf(material/form-field): add caching for shadow root
Browse files Browse the repository at this point in the history
Add caching for shadow root so it doesn't have to be resolved each time
  • Loading branch information
adumitrescu-plenty committed Jun 18, 2024
1 parent 5264fd2 commit 2c6befe
Showing 1 changed file with 22 additions and 1 deletion.
23 changes: 22 additions & 1 deletion src/material/form-field/form-field.ts
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,13 @@ export class MatFormField
private _explicitFormFieldControl: MatFormFieldControl<any>;
private _needsOutlineLabelOffsetUpdate = false;

/**
* Cached shadow root that the element is placed in. `null` means that the element isn't in
* the shadow DOM and `undefined` means that it hasn't been resolved yet. Should be read via
* `_getShadowRoot`, not directly.
*/
private _cachedShadowRoot: ShadowRoot | null | undefined;

private _injector = inject(Injector);

constructor(
Expand Down Expand Up @@ -709,7 +716,21 @@ export class MatFormField
rootNode !== element &&
// If the rootNode is the document we need to make sure that the element is visible
((rootNode === document && element.offsetParent !== null) ||
rootNode === _getShadowRoot(element))
rootNode === this._getShadowRoot())
);
}

/**
* Lazily resolves and returns the shadow root of the element. We do this in a function, rather
* than saving it in property directly on init, because we want to resolve it as late as possible
* in order to ensure that the element has been moved into the shadow DOM. Doing it inside the
* constructor might be too early if the element is inside of something like `ngFor` or `ngIf`.
*/
private _getShadowRoot(): ShadowRoot | null {
if (this._cachedShadowRoot === undefined) {
this._cachedShadowRoot = _getShadowRoot(this._elementRef.nativeElement);
}

return this._cachedShadowRoot;
}
}

0 comments on commit 2c6befe

Please sign in to comment.