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