Skip to content

Commit a4cf2dd

Browse files
committed
fix(material-experimental/mdc-chips): avoid unnecessary change detections
Avoids running the `transitionend` inside the `NgZone` for the MDC-based `mat-chip` since it fires a lot and it doesn't need to trigger change detection.
1 parent 20d3469 commit a4cf2dd

File tree

1 file changed

+14
-10
lines changed
  • src/material-experimental/mdc-chips

1 file changed

+14
-10
lines changed

src/material-experimental/mdc-chips/chip.ts

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ import {
1919
Directive,
2020
ElementRef,
2121
EventEmitter,
22-
HostListener,
2322
Inject,
2423
Input,
2524
NgZone,
@@ -151,13 +150,11 @@ export class MatChip extends _MatChipMixinBase implements AfterContentInit, Afte
151150
/** Whether animations for the chip are enabled. */
152151
_animationsDisabled: boolean;
153152

154-
// We have to use a `HostListener` here in order to support both Ivy and ViewEngine.
155-
// In Ivy the `host` bindings will be merged when this class is extended, whereas in
156-
// ViewEngine they're overwritten.
157-
// TODO(mmalerba): we move this back into `host` once Ivy is turned on by default.
158-
// tslint:disable-next-line:no-host-decorator-in-concrete
159-
@HostListener('transitionend', ['$event'])
160-
_handleTransitionEnd(event: TransitionEvent) {
153+
/**
154+
* Event listener for `transitionend` events. Needs to be an arrow
155+
* function so we can pass it easily into `addEventListener`.
156+
*/
157+
private _handleTransitionEnd = (event: TransitionEvent) => {
161158
this._chipFoundation.handleTransitionEnd(event);
162159
}
163160

@@ -338,7 +335,7 @@ export class MatChip extends _MatChipMixinBase implements AfterContentInit, Afte
338335

339336
constructor(
340337
public _changeDetectorRef: ChangeDetectorRef,
341-
readonly _elementRef: ElementRef, protected _ngZone: NgZone,
338+
readonly _elementRef: ElementRef<HTMLElement>, protected _ngZone: NgZone,
342339
@Optional() private _dir: Directionality,
343340
@Optional() @Inject(ANIMATION_MODULE_TYPE) animationMode?: string,
344341
@Optional() @Inject(MAT_RIPPLE_GLOBAL_OPTIONS)
@@ -348,6 +345,10 @@ export class MatChip extends _MatChipMixinBase implements AfterContentInit, Afte
348345
this._animationsDisabled = animationMode === 'NoopAnimations';
349346
this._isBasicChip = _elementRef.nativeElement.hasAttribute(this.basicChipAttrName) ||
350347
_elementRef.nativeElement.tagName.toLowerCase() === this.basicChipAttrName;
348+
349+
_ngZone.runOutsideAngular(() => {
350+
_elementRef.nativeElement.addEventListener('transitionend', this._handleTransitionEnd);
351+
});
351352
}
352353

353354
ngAfterContentInit() {
@@ -356,11 +357,14 @@ export class MatChip extends _MatChipMixinBase implements AfterContentInit, Afte
356357

357358
ngAfterViewInit() {
358359
this._chipFoundation.init();
359-
this._textElement = this._elementRef.nativeElement.querySelector('.mdc-chip__text');
360+
this._textElement =
361+
this._elementRef.nativeElement.querySelector('.mdc-chip__text') as HTMLElement;
360362
}
361363

362364
ngOnDestroy() {
363365
this.destroyed.emit({chip: this});
366+
this.destroyed.complete();
367+
this._elementRef.nativeElement.removeEventListener('transitionend', this._handleTransitionEnd);
364368
this._chipFoundation.destroy();
365369
}
366370

0 commit comments

Comments
 (0)