1.7 KiB
1.7 KiB
title, impact, impactDescription, tags
| title | impact | impactDescription | tags |
|---|---|---|---|
| Avoid Unnecessary Tracking | HIGH | 20-40% fewer invalidations | components, tracked, performance, reactivity |
Avoid Unnecessary Tracking
Only mark properties as @tracked if they need to trigger re-renders when changed. Overusing @tracked causes unnecessary invalidations and re-renders.
Incorrect (everything tracked):
import Component from '@glimmer/component';
import { tracked } from '@glimmer/tracking';
import { action } from '@ember/object';
class Form extends Component {
@tracked firstName = ''; // Used in template ✓
@tracked lastName = ''; // Used in template ✓
@tracked _formId = Date.now(); // Internal, never rendered ✗
@tracked _validationCache = new Map(); // Internal state ✗
@action
validate() {
this._validationCache.set('firstName', this.firstName.length > 0);
// Unnecessary re-render triggered
}
}
Correct (selective tracking):
import Component from '@glimmer/component';
import { tracked } from '@glimmer/tracking';
import { action } from '@ember/object';
class Form extends Component {
@tracked firstName = ''; // Rendered in template
@tracked lastName = ''; // Rendered in template
@tracked isValid = false; // Rendered status
_formId = Date.now(); // Not tracked - internal only
_validationCache = new Map(); // Not tracked - internal state
@action
validate() {
this._validationCache.set('firstName', this.firstName.length > 0);
this.isValid = this._validationCache.get('firstName');
// Only re-renders when isValid changes
}
}
Only track properties that directly affect the template or other tracked getters to minimize unnecessary re-renders.