面试题答案
一键面试1. 利用 trackBy
函数优化 NgFor
的性能
- 原理:
NgFor
在渲染列表时,默认会基于对象引用或数组索引来跟踪每个项目。当列表发生变化时,Angular 会重新渲染整个列表,即便只有部分项目真正改变。trackBy
函数允许开发者提供一个自定义的跟踪函数,让 Angular 能够更高效地识别变化的项目,从而只更新真正发生变化的部分,提升性能。 - 示例代码:
<ul>
<li *ngFor="let item of items; trackBy: trackByFn">{{item.name}}</li>
</ul>
import { Component } from '@angular/core';
@Component({
selector: 'app-example',
templateUrl: './example.component.html',
styleUrls: ['./example.component.css']
})
export class ExampleComponent {
items = [
{ id: 1, name: 'Item 1' },
{ id: 2, name: 'Item 2' },
{ id: 3, name: 'Item 3' }
];
trackByFn(index: number, item: any) {
return item.id; // 以 item 的 id 作为跟踪依据
}
}
2. 避免因 NgIf
频繁创建和销毁组件带来的性能损耗
- 策略一:使用
NgSwitch
代替频繁切换的NgIf
- 原理:
NgIf
会在条件为false
时完全销毁 DOM 及其内部组件,条件为true
时重新创建。而NgSwitch
会保留所有可能的分支,通过切换显示状态来实现不同视图的展示,避免了频繁的创建和销毁。 - 示例代码:
- 原理:
<div [ngSwitch]="condition">
<div *ngSwitchCase="'value1'">
<app-component1></app-component1>
</div>
<div *ngSwitchCase="'value2'">
<app-component2></app-component2>
</div>
<div *ngSwitchDefault>
<app-component3></app-component3>
</div>
</div>
import { Component } from '@angular/core';
@Component({
selector: 'app-example',
templateUrl: './example.component.html',
styleUrls: ['./example.component.css']
})
export class ExampleComponent {
condition = 'value1';
}
- 策略二:缓存
NgIf
内部组件状态- 原理:可以使用
@Output
和@Input
来保存和恢复组件的状态,这样在NgIf
销毁和重新创建组件时,能够快速恢复到之前的状态,减少初始化开销。 - 示例代码: 子组件(child.component.ts)
- 原理:可以使用
import { Component, Input, Output, EventEmitter } from '@angular/core';
@Component({
selector: 'app-child',
templateUrl: './child.component.html',
styleUrls: ['./child.component.css']
})
export class ChildComponent {
@Input() data: any;
@Output() dataChange = new EventEmitter<any>();
updateData(newData: any) {
this.data = newData;
this.dataChange.emit(newData);
}
}
父组件(parent.component.html)
<button (click)="toggle()">Toggle</button>
<ng-container *ngIf="isVisible">
<app-child [data]="cachedData" (dataChange)="cachedData = $event"></app-child>
</ng-container>
父组件(parent.component.ts)
import { Component } from '@angular/core';
@Component({
selector: 'app-parent',
templateUrl: './parent.component.html',
styleUrls: ['./parent.component.css']
})
export class ParentComponent {
isVisible = true;
cachedData = { initial: 'value' };
toggle() {
this.isVisible =!this.isVisible;
}
}