I've long been wondering whether to use a template full of getters, or just preconstruct the entire object with a resolver, and I can't really seem to find a clear answer anywhere.
I've created two simplified scenarios below.
Currently, I'm always using scenario 1, but as soon as the app/program becomes more complex, I notice (huge) performance drops, therefore I'm thinking about using scenario 2 from now on.
Scenario 1: Getter functions
Code:
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);
}
Template:
<div *ngFor="device in devices">
<i [class]="getIcon(device)"></i>
<span>{{ getTranslation(device) }}</span>
</div>
Scenario 2: Preconstruct the object
resolve
, it's easy to preconstruct the entire object, thus skipping all the getters in my template.Code:
var devices = [
{
item: 'desktop',
translation: 'Desktop',
icon: 'icon-desktop'
},
{
item: 'tablet',
translation: 'Tablet',
icon: 'icon-tablet'
},
{
item: 'mobile',
translation: 'Mobile',
icon: 'icon-mobile'
}
]
Template:
<div *ngFor="device in devices">
<i [class]="device.icon"></i>
<span>{{ device.translation }}</span>
</div>
Can anyone tell me the pros and cons of each scenario, and why? What about performance (my main question)? Personal preference or experience?
getTranslation(device)
will be called on each change detection cycle. This provides performance overhead but it is insignificant, as long as getTranslation
itself isn't costly.
A more conventional way is to use a pipe like {{ device | translation }}
. This can be pure pipe which is more efficient. But if the language is supposed to be changed dynamically, the pipe should be impure, because the expression evaluates to new value even if device
value is unchanged.