From 67ec1ae1dfc26794e285dd290bff136221a36f94 Mon Sep 17 00:00:00 2001 From: Yadong Xie Date: Sat, 13 Feb 2021 21:38:28 +0800 Subject: [PATCH] perf(module:select): avoid reflow when select init --- components/core/animation/zoom.ts | 22 ------------------ .../select/select-top-control.component.ts | 11 --------- components/select/select.component.ts | 21 ++++++++--------- .../tree-select/tree-select.component.ts | 23 ++++++------------- 4 files changed, 17 insertions(+), 60 deletions(-) diff --git a/components/core/animation/zoom.ts b/components/core/animation/zoom.ts index 0c8999599fb..72369e55e61 100644 --- a/components/core/animation/zoom.ts +++ b/components/core/animation/zoom.ts @@ -6,28 +6,6 @@ import { animate, AnimationTriggerMetadata, style, transition, trigger } from '@angular/animations'; import { AnimationCurves, AnimationDuration } from './animation-consts'; -export const zoomMotion: AnimationTriggerMetadata = trigger('zoomMotion', [ - transition(':enter', [ - style({ opacity: 0, transform: 'scale(0.2)' }), - animate( - `${AnimationDuration.BASE} ${AnimationCurves.EASE_OUT_CIRC}`, - style({ - opacity: 1, - transform: 'scale(1)' - }) - ) - ]), - transition(':leave', [ - style({ opacity: 1, transform: 'scale(1)' }), - animate( - `${AnimationDuration.BASE} ${AnimationCurves.EASE_IN_OUT_CIRC}`, - style({ - opacity: 0, - transform: 'scale(0.2)' - }) - ) - ]) -]); export const zoomBigMotion: AnimationTriggerMetadata = trigger('zoomBigMotion', [ transition('void => active', [ style({ opacity: 0, transform: 'scale(0.8)' }), diff --git a/components/select/select-top-control.component.ts b/components/select/select-top-control.component.ts index df74f01e54c..436f543a24e 100644 --- a/components/select/select-top-control.component.ts +++ b/components/select/select-top-control.component.ts @@ -19,7 +19,6 @@ import { ViewChild, ViewEncapsulation } from '@angular/core'; -import { zoomMotion } from 'ng-zorro-antd/core/animation'; import { NzNoAnimationDirective } from 'ng-zorro-antd/core/no-animation'; import { NzSafeAny } from 'ng-zorro-antd/core/types'; import { NzSelectSearchComponent } from './select-search.component'; @@ -29,7 +28,6 @@ import { NzSelectItemInterface, NzSelectModeType, NzSelectTopControlItemType } f selector: 'nz-select-top-control', exportAs: 'nzSelectTopControl', preserveWhitespaces: false, - animations: [zoomMotion], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: ` @@ -60,16 +58,12 @@ import { NzSelectItemInterface, NzSelectModeType, NzSelectTopControlItemType } f (); @Output() readonly inputValueChange = new EventEmitter(); - @Output() readonly animationEnd = new EventEmitter(); @Output() readonly deleteItem = new EventEmitter(); @ViewChild(NzSelectSearchComponent) nzSelectSearchComponent!: NzSelectSearchComponent; listOfSlicedItem: NzSelectTopControlItemType[] = []; @@ -197,10 +190,6 @@ export class NzSelectTopControlComponent implements OnChanges { } } - onAnimationEnd(): void { - this.animationEnd.next(); - } - constructor(private elementRef: ElementRef, @Host() @Optional() public noAnimation?: NzNoAnimationDirective) { // TODO: move to host after View Engine deprecation this.elementRef.nativeElement.classList.add('ant-select-selector'); diff --git a/components/select/select.component.ts b/components/select/select.component.ts index 1b457489a90..e7fed5d6b66 100644 --- a/components/select/select.component.ts +++ b/components/select/select.component.ts @@ -10,7 +10,6 @@ import { CdkConnectedOverlay, CdkOverlayOrigin, ConnectedOverlayPositionChange } import { Platform } from '@angular/cdk/platform'; import { AfterContentInit, - AfterViewInit, ChangeDetectionStrategy, ChangeDetectorRef, Component, @@ -31,10 +30,12 @@ import { ViewChild, ViewEncapsulation } from '@angular/core'; + import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms'; import { slideMotion } from 'ng-zorro-antd/core/animation'; import { NzConfigKey, NzConfigService, WithConfig } from 'ng-zorro-antd/core/config'; import { NzNoAnimationDirective } from 'ng-zorro-antd/core/no-animation'; +import { reqAnimFrame } from 'ng-zorro-antd/core/polyfill'; import { BooleanInput, NzSafeAny, OnChangeType, OnTouchedType } from 'ng-zorro-antd/core/types'; import { InputBoolean, isNotNil } from 'ng-zorro-antd/core/util'; import { BehaviorSubject, combineLatest, merge, Subject } from 'rxjs'; @@ -90,7 +91,6 @@ export type NzSelectSizeType = 'large' | 'default' | 'small'; [listOfTopItem]="listOfTopItem" (inputValueChange)="onInputValueChange($event)" (tokenize)="onTokenSeparate($event)" - (animationEnd)="updateCdkConnectedOverlayPositions()" (deleteItem)="onItemDelete($event)" (keydown)="onKeyDown($event)" > @@ -159,7 +159,7 @@ export type NzSelectSizeType = 'large' | 'default' | 'small'; '(click)': 'onHostClick()' } }) -export class NzSelectComponent implements ControlValueAccessor, OnInit, AfterViewInit, OnDestroy, AfterContentInit, OnChanges { +export class NzSelectComponent implements ControlValueAccessor, OnInit, OnDestroy, AfterContentInit, OnChanges { readonly _nzModuleName: NzConfigKey = NZ_CONFIG_MODULE_NAME; static ngAcceptInputType_nzAllowClear: BooleanInput; @@ -478,14 +478,17 @@ export class NzSelectComponent implements ControlValueAccessor, OnInit, AfterVie updateCdkConnectedOverlayStatus(): void { if (this.platform.isBrowser && this.originElement.nativeElement) { - this.triggerWidth = this.originElement.nativeElement.getBoundingClientRect().width; + reqAnimFrame(() => { + this.triggerWidth = this.originElement.nativeElement.getBoundingClientRect().width; + this.cdr.markForCheck(); + }); } } updateCdkConnectedOverlayPositions(): void { - if (this.cdkConnectedOverlay.overlayRef) { - this.cdkConnectedOverlay.overlayRef.updatePosition(); - } + reqAnimFrame(() => { + this.cdkConnectedOverlay?.overlayRef?.updatePosition(); + }); } constructor( @@ -605,10 +608,6 @@ export class NzSelectComponent implements ControlValueAccessor, OnInit, AfterVie this.dir = this.directionality.value; } - ngAfterViewInit(): void { - this.updateCdkConnectedOverlayStatus(); - } - ngAfterContentInit(): void { if (!this.isReactiveDriven) { merge(this.listOfNzOptionGroupComponent.changes, this.listOfNzOptionComponent.changes) diff --git a/components/tree-select/tree-select.component.ts b/components/tree-select/tree-select.component.ts index f33461b0f35..a3972041440 100644 --- a/components/tree-select/tree-select.component.ts +++ b/components/tree-select/tree-select.component.ts @@ -4,6 +4,8 @@ */ import { FocusMonitor } from '@angular/cdk/a11y'; + +import { Direction, Directionality } from '@angular/cdk/bidi'; import { BACKSPACE, ESCAPE, TAB } from '@angular/cdk/keycodes'; import { CdkConnectedOverlay, CdkOverlayOrigin, ConnectedOverlayPositionChange } from '@angular/cdk/overlay'; import { @@ -28,9 +30,10 @@ import { ViewChild } from '@angular/core'; import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms'; -import { slideMotion, zoomMotion } from 'ng-zorro-antd/core/animation'; +import { slideMotion } from 'ng-zorro-antd/core/animation'; import { NzConfigKey, NzConfigService, WithConfig } from 'ng-zorro-antd/core/config'; import { NzNoAnimationDirective } from 'ng-zorro-antd/core/no-animation'; +import { reqAnimFrame } from 'ng-zorro-antd/core/polyfill'; import { NzFormatEmitEvent, @@ -47,8 +50,6 @@ import { NzTreeComponent } from 'ng-zorro-antd/tree'; import { merge, of as observableOf, Subject, Subscription } from 'rxjs'; import { filter, takeUntil, tap } from 'rxjs/operators'; - -import { Direction, Directionality } from '@angular/cdk/bidi'; import { NzTreeSelectService } from './tree-select.service'; export function higherOrderServiceFactory(injector: Injector): NzTreeBaseService { @@ -61,7 +62,7 @@ const TREE_SELECT_DEFAULT_CLASS = 'ant-select-dropdown ant-select-tree-dropdown' @Component({ selector: 'nz-tree-select', exportAs: 'nzTreeSelect', - animations: [slideMotion, zoomMotion], + animations: [slideMotion], template: ` { - if (this.cdkConnectedOverlay && this.cdkConnectedOverlay.overlayRef) { - this.cdkConnectedOverlay.overlayRef.updatePosition(); - } + reqAnimFrame(() => { + this.cdkConnectedOverlay?.overlayRef?.updatePosition(); }); }