*中的光标,我们会看到这个函数在很短的时间内被执行了数百次。
![1_ywSGT-0_5NMgiglTtO8IkA.png][3]
起初只有几个函数调用,影响可能不大。然而,当越来越多的新组件被添加到应用程序中时,它们会以指数形式堆积起来,最终吞噬了所有的计算能力,使应用程序变得缓慢。
有些人可能会想到使用getter方法来避免函数调用。但事实上,这并不可行,因为getter方法也是一个函数调用,这也有同样的问题。
```
import { Component } from '@angular/core';
@Component({
selector: 'app-performance-issue',
template: `
{{ name }}
`,
})
export class PerformanceIssueComponent {
names = ['Maria', 'Michel', 'Jack', 'John', 'Sam', 'Mila'];
counter = 0;
get filteredNames(): string[] {
this.counter++
console.log("filterNames() called! " + this.counter + " times!");
return this.names.filter(name => name.startsWith('M'));
}
onMousemove() {
console.log('Mouse moved');
}
}
```
![1_jCmltyjtNqlzGb8pEKkU2w.png][4]
The Solution
------------
事实上,这个问题并没有完美的解决方案。Angular必须在变化检测期间重新执行模板内的所有函数,这是其设计的一个局限性。一个可能的变通方法是避免带有复杂计算的模板函数调用。如果我们需要有一些计算值,我们应该自己手动管理,而不是依赖Angular的变化检测。
Solution1 — 使用 setter function
------------------------------
```
import {Component, Input} from '@angular/core';
@Component({
selector: 'app-performance-issue',
template: `
{{ name }}
`,
})
export class PerformanceIssueComponent {
filteredNames = []
@Input() set names(value: string[]) {
this.filteredNames = value.filter(name => name.startsWith('M'));
}
}
```
Solution2 — 使用 ngOnChanges
--------------------------
```
import {Component, Input, OnChanges, SimpleChanges} from '@angular/core';
@Component({
selector: 'app-performance-issue',
template: `
{{ name }}
`,
})
export class PerformanceIssueComponent implements OnChanges{
@Input() names = []
filteredNames = []
ngOnChanges(changes: SimpleChanges): void {
if (changes.value) {
this.filteredNames = this.names.filter(name => name.startsWith('M'));
}
}
}
```
[1]: http://guobacai.com/usr/uploads/2021/10/2510547019.jpg
[2]: http://guobacai.com/usr/uploads/2021/10/825491543.png
[3]: http://guobacai.com/usr/uploads/2021/10/2531700720.png
[4]: http://guobacai.com/usr/uploads/2021/10/3882566673.png
评论已关闭