Angular:预构造对象与模板获取器
Angular: preconstructed object vs template getters
我一直在想是使用充满 getter 的模板,还是使用解析器预先构造整个对象,但我似乎无法在任何地方找到明确的答案。
我在下面创建了两个简化的场景。
目前,我一直在使用场景 1,但是一旦 app/program 变得更加复杂,我注意到(巨大的)性能下降,因此我正在考虑从现在开始使用场景 2。
场景 1:Getter 函数
- 专业版:您只需 get/use 当前模板中需要的任何内容。添加新的 getter 不需要更新接口。
- 缺点:在单个模板中有 hundreds/thousands 个 getter 时对性能的影响(我认为)。
代码:
var devices = ['desktop', 'tablet', 'mobile'];
var icons = {
desktop: 'icon-desktop',
tablet: 'icon-tablet',
mobile: 'icon-mobile'
}
var translations = {
desktop: 'Desktop',
tablet: 'Tablet',
mobile: 'Mobile'
}
getIcon(item: string): string {
return icons(type);
}
getTranslation(item: string): string {
return translations(type);
}
模板:
<div *ngFor="device in devices">
<i [class]="getIcon(device)"></i>
<span>{{ getTranslation(device) }}</span>
</div>
场景二:预构造对象
- 优点:使用
resolve
,可以轻松预构造整个对象,从而跳过我模板中的所有 getter。
- Pro: 对象永远不会改变,因此 Angular 不必 'watch' 它。
- 缺点:对象可能会变得很大,很多属性可能永远不会被使用。
代码:
var devices = [
{
item: 'desktop',
translation: 'Desktop',
icon: 'icon-desktop'
},
{
item: 'tablet',
translation: 'Tablet',
icon: 'icon-tablet'
},
{
item: 'mobile',
translation: 'Mobile',
icon: 'icon-mobile'
}
]
模板:
<div *ngFor="device in devices">
<i [class]="device.icon"></i>
<span>{{ device.translation }}</span>
</div>
谁能告诉我每种情况的优缺点,为什么?性能如何(我的主要问题)?个人喜好或经验?
getTranslation(device)
将在每个更改检测周期调用。这提供了性能开销,但它是微不足道的,只要 getTranslation
本身并不昂贵。
更传统的方法是使用像{{ device | translation }}
这样的管道。这可以是效率更高的 纯管道 。但是,如果语言应该动态更改,则管道应该是不纯的,因为即使 device
值未更改,表达式也会计算出新值。
根据我的经验,使用在模板中调用的 getter 将比函数调用近 100%。您可以通过在每个 console.count()
中插入一个 console.count()
来测试它。
取决于您使用 OnPush
更改检测策略的应用或组件,这将大大减少调用。
我一直在想是使用充满 getter 的模板,还是使用解析器预先构造整个对象,但我似乎无法在任何地方找到明确的答案。
我在下面创建了两个简化的场景。
目前,我一直在使用场景 1,但是一旦 app/program 变得更加复杂,我注意到(巨大的)性能下降,因此我正在考虑从现在开始使用场景 2。
场景 1:Getter 函数
- 专业版:您只需 get/use 当前模板中需要的任何内容。添加新的 getter 不需要更新接口。
- 缺点:在单个模板中有 hundreds/thousands 个 getter 时对性能的影响(我认为)。
代码:
var devices = ['desktop', 'tablet', 'mobile'];
var icons = {
desktop: 'icon-desktop',
tablet: 'icon-tablet',
mobile: 'icon-mobile'
}
var translations = {
desktop: 'Desktop',
tablet: 'Tablet',
mobile: 'Mobile'
}
getIcon(item: string): string {
return icons(type);
}
getTranslation(item: string): string {
return translations(type);
}
模板:
<div *ngFor="device in devices">
<i [class]="getIcon(device)"></i>
<span>{{ getTranslation(device) }}</span>
</div>
场景二:预构造对象
- 优点:使用
resolve
,可以轻松预构造整个对象,从而跳过我模板中的所有 getter。 - Pro: 对象永远不会改变,因此 Angular 不必 'watch' 它。
- 缺点:对象可能会变得很大,很多属性可能永远不会被使用。
代码:
var devices = [
{
item: 'desktop',
translation: 'Desktop',
icon: 'icon-desktop'
},
{
item: 'tablet',
translation: 'Tablet',
icon: 'icon-tablet'
},
{
item: 'mobile',
translation: 'Mobile',
icon: 'icon-mobile'
}
]
模板:
<div *ngFor="device in devices">
<i [class]="device.icon"></i>
<span>{{ device.translation }}</span>
</div>
谁能告诉我每种情况的优缺点,为什么?性能如何(我的主要问题)?个人喜好或经验?
getTranslation(device)
将在每个更改检测周期调用。这提供了性能开销,但它是微不足道的,只要 getTranslation
本身并不昂贵。
更传统的方法是使用像{{ device | translation }}
这样的管道。这可以是效率更高的 纯管道 。但是,如果语言应该动态更改,则管道应该是不纯的,因为即使 device
值未更改,表达式也会计算出新值。
根据我的经验,使用在模板中调用的 getter 将比函数调用近 100%。您可以通过在每个 console.count()
中插入一个 console.count()
来测试它。
取决于您使用 OnPush
更改检测策略的应用或组件,这将大大减少调用。