When it comes to performance, it is best practice to avoid having function calls directly in the template as they are executed every change detection cycle. To improve this, consider updating a member variable with the desired values before displaying them.
@Component({
selector: 'app-component',
template: '
<table>
<thead>
<tr>
<th>Date</th>
<th>Time left</th>
</tr>
</thead>
<tbody>
<tr *ngFor="time in times">
<td>{{time.date}}</td>
<td>{{time.counter | async}}</td>
</tr>
</tbody>
</table>
'
})
export class MyComponent {
public times;
constructor() {
// Create an observable triggered every second.
// Observable.interval(1000).subscribe(_ => this.time = myXYZFunction());
}
setupTimes() {
const rawTimes = this.getTimes();
this.times = [];
rawTimes.forEach(tm => this.times.push({date: tm, counter: this.setupCounter(tm)});
}
setupCounter(time) {
return Observable.interval(1000).pipe(map(_ => myXYZFunction(time)));
}
/**
* Retrieve dates for display from the backend or use a static array.
*/
getTimes(): number[]{
return [];
}
}
By controlling when your function is called, you can reduce unnecessary load and eliminate UI lag. It's important to note that displaying real-time data in a table may result in performance issues, so consider adjusting update intervals to minimize browser load.
UPDATE
The example has been updated to reflect displaying date and countdown timer in a table. Creating objects from these values aims to optimize performance, although frequent updates for multiple dates might still impact performance. Utilizing the async pipe eliminates the need for manual unsubscribing. For less demanding accuracy, consider increasing the interval between counters to reduce browser strain.
setupCounter(time) { // Updated every minute.
return Observable.interval(60000).pipe(map(_ => myXYZFunction(time)));
}