Skip to content
This repository was archived by the owner on Oct 29, 2024. It is now read-only.

Commit e3be65f

Browse files
committed
Add docs from RFC 556
1 parent 23b17f9 commit e3be65f

File tree

1 file changed

+57
-0
lines changed

1 file changed

+57
-0
lines changed

packages/@glimmer/tracking/src/cached.ts

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,63 @@
11
import { DEBUG } from '@glimmer/env';
22
import { createCache, getValue } from '@glimmer/validator';
33

4+
/**
5+
* @decorator
6+
*
7+
* The `@cached` decorator can be used on getters in order to cache the return
8+
* value of the getter. This is useful when a getter is expensive and used very
9+
* often.
10+
*
11+
*
12+
* @example
13+
*
14+
* in this guest list class, we have the `sortedGuests`
15+
* getter that sorts the guests alphabetically:
16+
*
17+
* ```js
18+
* import { tracked } from '@glimmer/tracking';
19+
*
20+
* class GuestList {
21+
* @tracked guests = ['Zoey', 'Tomster'];
22+
*
23+
* get sortedGuests() {
24+
* return this.guests.slice().sort()
25+
* }
26+
* }
27+
* ```
28+
*
29+
* Every time `sortedGuests` is accessed, a new array will be created and sorted,
30+
* because JavaScript getters do not cache by default. When the guest list is
31+
* small, like the one in the example, this is not a problem. However, if the guest
32+
* list were to grow very large, it would mean that we would be doing a large
33+
* amount of work each time we accessed `sortedGetters`. With `@cached`, we can
34+
* cache the value instead:
35+
*
36+
* ```js
37+
* import { tracked, cached } from '@glimmer/tracking';
38+
*
39+
* class GuestList {
40+
* @tracked guests = ['Zoey', 'Tomster'];
41+
*
42+
* @cached
43+
* get sortedGuests() {
44+
* return this.guests.slice().sort()
45+
* }
46+
* }
47+
* ```
48+
*
49+
* Now the `sortedGuests` getter will be cached based on _autotracking_. It will
50+
* only rerun and create a new sorted array when the `guests` tracked property is
51+
* updated.
52+
*
53+
* In general, you should avoid using `@cached` unless you have confirmed that the
54+
* getter you are decorating is computationally expensive. `@cached` adds a small
55+
* amount of overhead to the getter, making it more expensive. While this overhead
56+
* is small, if `@cached` is overused it can add up to a large impact overall in
57+
* your app. Many getters and tracked properties are only accessed once, rendered,
58+
* and then never rerendered, so adding `@cached` when it is unnecessary can
59+
* negatively impact performance.
60+
*/
461
// eslint-disable-next-line @typescript-eslint/no-explicit-any
562
export const cached: PropertyDecorator = (...args: any[]) => {
663
const [target, key, descriptor] = args;

0 commit comments

Comments
 (0)