jeudi 24 septembre 2020

Is this a valid usage of @cached for autotracking of Ember Octane?

Recently I encounted an use case of @cached from tracked-toolbox when writing a glimmer component with autotracking. Here is an example code snippet:

import Component from '@glimmer/component';

/**
 * Example usage
 * <PersonInfo
 *  @a=
 *  @b=
 *  @c=
 * />
 * Where objA can be a large object
 */

export default class PersonInfo extends Component {

  /**
   * I hope @cached here can help avoid re-running output getter in each
   * of the other getters, e.g. this.msg, this.link, this.name
   * But whenever any input args changes it triggers update 
   * (i.e. parent run this.objA = newObj)
   */
  get output() {
    return someExpensiveLogic(this.args.a, this.args.b, this.args.c);
  }

  get msg() {
    return translate(this.output.msg);
  }

  get link() {
    return convert(this.output.link);
  }

  get name() {
    return change(this.output.name);
  }
}

<div>
  
  
  
</div>

Without using @cached, the above code will execute the output getter 3 times when rendering, once for each of msg, link and name.

I also thought about building my own cache for output, but it requires me to manually keep track of which state is used and hash them, which could be expensive and hard to maintain.

From my understanding, what @cached provides is an access to the "global tag" in the auto tracking system, so I can rely on that tag to determine when the cache needs refresh.

Since this is not supported in voyager-web as for now, I hope this usage can encourage us to add such support later.

Note: I found that @cached is convenient wrapper of

import { createCache, getValue } from '@glimmer/tracking/primitives/cache';

So fundamentally what I need is @glimmer/tracking/primitives/cache.




Aucun commentaire:

Enregistrer un commentaire