Back to Ember Js

Autotracked Rendering

internal-docs/guides/reactivity/autotracked-rendering.md

5.12.06.1 KB
Original Source

Autotracked Rendering

An explanation of the depths of the reactivity system we've been using and refining since Ember Octane (ember-source 3.13+).

Walkthrough: setting a value

Given:

gjs
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

  1. observe a render,
  2. and then click the button,
    • and then observe the output count update.

How does it work?

There are a few systems at play for autotracking:

  • [tags]1
  • [global context]2
  • the environment / delegate
  • some [glue code]3 that [configures]4 the [timing specifics]5 of when to [render updates]6
  • the actual [call to the VM to render]7

1. leading up to observing a render

2. click the button

  • increment()
    • read: count

      • reading is part of variable++ behavior
    • set: count

    • scheduleRevalidate() is called by dirtyTag(), which then defers to ember to call these things and interacts with the scheduler (we go back to step 1):

      • env.begin
      • env.rerender
      • read: count
      • env.commit

the output, count is rendered as 1

A minimal renderer

JSBin, here

[!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.

Footnotes

  1. https://github.com/glimmerjs/glimmer-vm/blob/d86274816a21c61fbc82059006fe7687ca17dc7e/packages/%40glimmer/validator/lib/validators.ts#L1

  2. https://github.com/emberjs/ember.js/blob/132b66a768a9cabd461908682ef331f35637d5e9/packages/%40ember/-internals/glimmer/lib/environment.ts#L21

  3. https://github.com/emberjs/ember.js/blob/132b66a768a9cabd461908682ef331f35637d5e9/packages/%40ember/-internals/glimmer/lib/renderer.ts#L613C1-L614C1

  4. https://github.com/emberjs/ember.js/blob/132b66a768a9cabd461908682ef331f35637d5e9/packages/%40ember/-internals/glimmer/lib/renderer.ts#L626

  5. https://github.com/emberjs/ember.js/blob/132b66a768a9cabd461908682ef331f35637d5e9/packages/%40ember/-internals/glimmer/lib/renderer.ts#L573

  6. https://github.com/emberjs/ember.js/blob/132b66a768a9cabd461908682ef331f35637d5e9/packages/%40ember/-internals/glimmer/lib/renderer.ts#L524

  7. https://github.com/emberjs/ember.js/blob/132b66a768a9cabd461908682ef331f35637d5e9/packages/%40ember/-internals/glimmer/lib/renderer.ts#L156