internal-docs/guides/reactivity/autotracked-rendering.md
An explanation of the depths of the reactivity system we've been using and refining since Ember Octane (ember-source 3.13+).
Given:
import { tracked } from '@glimmer/tracking';
class ModuleState {
@tracked count = 0;
increment() {
this.count++;
}
}
const state = new ModuleState();
<template>
<output>{{ state.count }}</output>
<button {{on "click" state.increment}}>Increment</button>
</template>
And we
How does it work?
There are a few systems at play for autotracking:
render
renderMain() from glimmer-vm
read: count
access count, which @tracked's getter defers to trackedData
trackedData is in @glimmer/validator instead of using tags directly.
trackedData calls consumeTag when the value is accessconsumeTag adds the tag to the CURRENT_TRACKER
{{ }} regions of a template "detect" a dirty tag, they can individually re-renderendTrackFrame()render a button with modifier
increment()
read: count
variable++ behaviorset: count
@tracked's setterscheduleRevalidate() is called by dirtyTag(), which then defers to ember to call these things and interacts with the scheduler (we go back to step 1):
the output, count is rendered as 1
[!CAUTION] This is heavy in boilerplate, and mostly private API. This 300 line minimal example, should be considered our todo list, as having all this required to render a tiny component is too much.
https://github.com/glimmerjs/glimmer-vm/blob/d86274816a21c61fbc82059006fe7687ca17dc7e/packages/%40glimmer/validator/lib/validators.ts#L1 ↩
https://github.com/emberjs/ember.js/blob/132b66a768a9cabd461908682ef331f35637d5e9/packages/%40ember/-internals/glimmer/lib/environment.ts#L21 ↩
https://github.com/emberjs/ember.js/blob/132b66a768a9cabd461908682ef331f35637d5e9/packages/%40ember/-internals/glimmer/lib/renderer.ts#L613C1-L614C1 ↩
https://github.com/emberjs/ember.js/blob/132b66a768a9cabd461908682ef331f35637d5e9/packages/%40ember/-internals/glimmer/lib/renderer.ts#L626 ↩
https://github.com/emberjs/ember.js/blob/132b66a768a9cabd461908682ef331f35637d5e9/packages/%40ember/-internals/glimmer/lib/renderer.ts#L573 ↩
https://github.com/emberjs/ember.js/blob/132b66a768a9cabd461908682ef331f35637d5e9/packages/%40ember/-internals/glimmer/lib/renderer.ts#L524 ↩
https://github.com/emberjs/ember.js/blob/132b66a768a9cabd461908682ef331f35637d5e9/packages/%40ember/-internals/glimmer/lib/renderer.ts#L156 ↩