Skip to content

Render Transformer

Converts JSX render methods into zero-DOM factory function calls for efficient rendering.

Input: JSX render method

render() {
return (
<div class="container">
<h1>Hello {this.name}</h1>
<ul>
{this.todos.map((todo) => (
<li key={todo.id}>{todo.text}</li>
))}
</ul>
</div>
);
}

Output: Factory function calls

render() {
let $0 = this.#cmc("div_0", () => dce("div"));
sp($0, { class: "container" });
let $1 = this.#cmc("h1_1", () => dce("h1"));
let $1_text_2 = this.#cmc("$1_text_2", () => dctn("Hello "));
sc($1, [$1_text_2, this.name]);
let $3 = this.#cmc("ul_3", () => dce("ul"));
sc($3, [
this.todos.map((todo) => {
let $4 = this.#cmc("li_4_" + todo.id, () => dce("li"));
let $4_text_5 = this.#cmc("$4_text_5_" + todo.id, () => dctn(""));
sc($4, [$4_text_5, todo.text]);
return $4;
}),
]);
sc($0, [$1, $3]);
sc(this, [$0]);
}

Key factory functions:

  • dce() – Create element
  • dctn() – Create text node
  • sp() – Set property
  • sc() – Set children
  • ael() – Add event listener
  • cmc() – Memoization cache

Three specialized modules:

  • render.ts – Orchestrates AST traversal; dispatches JSX and loops
  • render.jsx.ts – Converts JSX into factory calls with memoization
  • render.loop.ts – Tracks nesting depth, builds hierarchical scope keys

Hierarchical Memoization Keys – Nested loops prevent cache collisions:

  • Single loop: "li_4_" + todo.id
  • Nested (2 levels): "span_2_index_index1" + cell.id

Index Naming – Depths 0, 1, 2 use index, index1, index2.

Prepended Statements – Execute inside loop callbacks, not outside.

IssueRoot CauseFix
Double element creationStatements bubble to parentWrap in block inside callback
Missing index parameterIndex not in key attributesCheck for “index” in keys
Incorrect cache keysHierarchical scope missingVerify scope key building joins all stack entries