Skip to content

Commit

Permalink
Document the caching of autotracked properties
Browse files Browse the repository at this point in the history
  • Loading branch information
YoranBrondsema committed Jul 7, 2020
1 parent cf9506d commit 08f68dd
Showing 1 changed file with 84 additions and 0 deletions.
84 changes: 84 additions & 0 deletions guides/release/in-depth-topics/autotracking-in-depth.md
Original file line number Diff line number Diff line change
Expand Up @@ -321,4 +321,88 @@ class ShoppingList {
}
```

## Caching of tracked properties

In contrast with computed properties from pre-Octane, autotracked properties
are not cached. This means that an autotracked property will always be
recomputed, regardless of whether its dependencies have changed. The following
example shows how this works:

```js
import { tracked } from '@glimmer/tracking';

let count = 0;

class Person {
@tracked firstName = 'Jen';
@tracked lastName = 'Weber';

get fullName() {
++count;
return `${this.firstName} ${this.lastName}`;
}
}

let person = new Person();

console.log(person.fullName); // Jen Weber
console.log(count); // 1;
console.log(person.fullName); // Jen Weber
console.log(count); // 2;

person.firstName = 'Jennifer';

console.log(person.fullName); // Jennifer Weber
console.log(count); // 3;
```

This works fine in most cases. But sometimes you want a bit more control over
the recomputation, for instance if the computation that happens in the getter
is very expensive. In that case, you want to cache the value in between calls
when the dependencies haven't changed. You want to recompute only if one of the
dependencies has been modified.

The way to achieve this is through Ember's [cache
API](https://github.com/emberjs/rfcs/blob/master/text/0615-autotracking-memoization.md).
It's not yet available in Ember.js core but you can use the API today with the
[ember-cache-primitive-polyfill](https://github.com/ember-polyfills/ember-cache-primitive-polyfill)
addon.

Using `createCache`, we can cache an autotracked property. The property can
then be consumed with the `getValue` function. The way it works is as follows:

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

let count = 0;

class Person {
@tracked firstName = 'Jen';
@tracked lastName = 'Weber';

// `#` indicates a private field on the class.
#fullNameCache = createCache(() => {
++count;
return `${this.firstName} ${this.lastName}`;
})

get fullName() {
return getValue(this.#fullNameCache);
}
}

let person = new Person();

console.log(person.fullName); // Jen Weber
console.log(count); // 1;
console.log(person.fullName); // Jen Weber
console.log(count); // 1;

person.firstName = 'Jennifer';

console.log(person.fullName); // Jennifer Weber
console.log(count); // 2;
```

<!-- eof - needed for pages that end in a code block -->

0 comments on commit 08f68dd

Please sign in to comment.