Files
marco/.agents/skills/ember-best-practices/rules/component-cached-getters.md

1.7 KiB

title, impact, impactDescription, tags
title impact impactDescription tags
Use @cached for Expensive Getters HIGH 50-90% reduction in recomputation 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):

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):

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