--- title: Use @cached for Expensive Getters impact: HIGH impactDescription: 50-90% reduction in recomputation tags: components, performance, caching, tracked --- ## Use @cached for Expensive Getters Use `@cached` from `@glimmer/tracking` to memoize expensive computations that depend on tracked properties. The cached value is automatically invalidated when dependencies change. **Incorrect (recomputes on every access):** ```javascript import Component from '@glimmer/component'; class DataTable extends Component { get filteredAndSortedData() { // Expensive: runs on every access, even if nothing changed return this.args.data .filter((item) => item.status === this.args.filter) .sort((a, b) => a[this.args.sortBy] - b[this.args.sortBy]) .map((item) => this.transformItem(item)); } } ``` **Correct (cached computation):** ```javascript import Component from '@glimmer/component'; import { cached } from '@glimmer/tracking'; class DataTable extends Component { @cached get filteredAndSortedData() { // Computed once per unique combination of dependencies return this.args.data .filter((item) => item.status === this.args.filter) .sort((a, b) => a[this.args.sortBy] - b[this.args.sortBy]) .map((item) => this.transformItem(item)); } transformItem(item) { // Expensive transformation return { ...item, computed: this.expensiveCalculation(item) }; } } ``` `@cached` memoizes the getter result and only recomputes when tracked dependencies change, providing 50-90% reduction in unnecessary work. Reference: [@cached decorator](https://guides.emberjs.com/release/in-depth-topics/autotracking-in-depth/#toc_caching)