Skip to content

Commit

Permalink
perf(module:avatar): do not run change detection on timer and update …
Browse files Browse the repository at this point in the history
…styles directly (#7862)
  • Loading branch information
arturovt committed Mar 29, 2023
1 parent 1171460 commit 1c48745
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 24 deletions.
37 changes: 14 additions & 23 deletions components/avatar/avatar.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,20 +11,15 @@ import {
ElementRef,
EventEmitter,
Input,
NgZone,
OnChanges,
Output,
ViewChild,
ViewEncapsulation
} from '@angular/core';

import { NzConfigKey, NzConfigService, WithConfig } from 'ng-zorro-antd/core/config';
import {
NgClassInterface,
NgStyleInterface,
NumberInput,
NzShapeSCType,
NzSizeLDSType
} from 'ng-zorro-antd/core/types';
import { NgClassInterface, NumberInput, NzShapeSCType, NzSizeLDSType } from 'ng-zorro-antd/core/types';
import { InputNumber } from 'ng-zorro-antd/core/util';

const NZ_CONFIG_MODULE_NAME: NzConfigKey = 'avatar';
Expand All @@ -35,7 +30,7 @@ const NZ_CONFIG_MODULE_NAME: NzConfigKey = 'avatar';
template: `
<span nz-icon *ngIf="nzIcon && hasIcon" [nzType]="nzIcon"></span>
<img *ngIf="nzSrc && hasSrc" [src]="nzSrc" [attr.srcset]="nzSrcSet" [attr.alt]="nzAlt" (error)="imgError($event)" />
<span class="ant-avatar-string" #textEl [ngStyle]="textStyles" *ngIf="nzText && hasText">{{ nzText }}</span>
<span class="ant-avatar-string" #textEl *ngIf="nzText && hasText">{{ nzText }}</span>
`,
host: {
class: 'ant-avatar',
Expand Down Expand Up @@ -72,19 +67,19 @@ export class NzAvatarComponent implements OnChanges {
hasText: boolean = false;
hasSrc: boolean = true;
hasIcon: boolean = false;
textStyles: NgStyleInterface = {};
classMap: NgClassInterface = {};
customSize: string | null = null;

@ViewChild('textEl', { static: false }) textEl?: ElementRef;
@ViewChild('textEl', { static: false }) textEl?: ElementRef<HTMLSpanElement>;

private el: HTMLElement = this.elementRef.nativeElement;

constructor(
public nzConfigService: NzConfigService,
private elementRef: ElementRef,
private cdr: ChangeDetectorRef,
private platform: Platform
private platform: Platform,
private ngZone: NgZone
) {}

imgError($event: Event): void {
Expand Down Expand Up @@ -118,27 +113,23 @@ export class NzAvatarComponent implements OnChanges {
return;
}

const childrenWidth = this.textEl!.nativeElement.offsetWidth;
const textEl = this.textEl!.nativeElement;
const childrenWidth = textEl.offsetWidth;
const avatarWidth = this.el.getBoundingClientRect().width;
const offset = this.nzGap * 2 < avatarWidth ? this.nzGap * 2 : 8;
const scale = avatarWidth - offset < childrenWidth ? (avatarWidth - offset) / childrenWidth : 1;

this.textStyles = {
transform: `scale(${scale}) translateX(-50%)`
};
if (this.customSize) {
Object.assign(this.textStyles, {
lineHeight: this.customSize
});
}
this.cdr.detectChanges();
textEl.style.transform = `scale(${scale}) translateX(-50%)`;
textEl.style.lineHeight = this.customSize || '';
}

private notifyCalc(): void {
// If use ngAfterViewChecked, always demands more computations, so......
if (this.platform.isBrowser) {
setTimeout(() => {
this.calcStringSize();
this.ngZone.runOutsideAngular(() => {
setTimeout(() => {
this.calcStringSize();
});
});
}
}
Expand Down
16 changes: 15 additions & 1 deletion components/avatar/avatar.spec.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Component, DebugElement, ViewChild } from '@angular/core';
import { ComponentFixture, fakeAsync, TestBed, tick } from '@angular/core/testing';
import { ComponentFixture, fakeAsync, flush, TestBed, tick } from '@angular/core/testing';
import { By } from '@angular/platform-browser';

import { createFakeEvent } from 'ng-zorro-antd/core/testing';
Expand Down Expand Up @@ -224,6 +224,20 @@ describe('avatar', () => {
fixture.detectChanges();
expect(hostStyle.fontSize === `${context.nzSize / 2}px`).toBe(true);
});

it('should set `lineHeight` on the text element considering `nzSize`', fakeAsync(() => {
const size = 64;
context.nzIcon = null;
context.nzSrc = null;
context.nzSize = size;
context.nzText = 'LongUsername';
fixture.detectChanges();
flush();
const textEl = document.querySelector<HTMLElement>('.ant-avatar-string')!;
const scale = getScaleFromCSSTransform(textEl.style.transform);
expect(scale).toBeLessThan(1);
expect(textEl.style.lineHeight).toEqual(`${size}px`);
}));
});

describe('order: image > icon > text', () => {
Expand Down

0 comments on commit 1c48745

Please sign in to comment.