Template
wybthon.template¶
template
¶
Template-based mounting: static HTML serialization plus hole wiring.
This module is the runtime analogue of SolidJS's compiled templates. A
run-once component returns a VNode tree whose structure is static; only
reactive holes, event handlers, refs, and reactive prop bindings change
after mount. That means the static skeleton can be serialized to an HTML
string in Python (cheap) and registered with the rendering kernel once;
every mount of the same skeleton is a single CLONE_TPL op that clones
the pre-parsed tree natively. The kernel then walks the clone in
document order, assigning a dense block of node ids.
Because the Python serializer counts nodes in exactly the same pre-order
the kernel walks, every element, text node, and placeholder comment gets
a predictable id with zero extra communication: the mount simply
assigns first_id + k to the k-th serialized node.
Static text content is hoisted out of the HTML: the serializer emits
a one-space placeholder text node and records the real value as a
SET_TEXT binding applied after the clone. Hoisting is what makes
templates shared: a thousand list rows that differ only in their text
(ids, labels) produce the same skeleton string, so the browser parses
it once and clones it a thousand times.
The pipeline:
build_planwalks a VNode tree and produces aMountPlan: the serialized HTML, the pre-order node list (for id assignment and text bindings), the dynamic bindings (events, reactive props, refs, DOM-property writes), orNonewhen the tree isn't eligible for the fast path.- The reconciler registers the HTML (once per unique skeleton),
allocates the id block, emits the
CLONE_TPLop, applies bindings by id, and mounts dynamic children (holes, fragments, components) at their placeholder comments.
Trees fall back to per-node ops (still batched, still one bridge
crossing) when they contain constructs the HTML parser would mangle:
adjacent or empty text nodes, raw text elements, invalid attribute
names, or element nestings the parser rewrites (implied <tbody>,
auto-closed <p>, and similar).
Plans are cached per shape: a single walk of the VNode tree collects the per-instance data (id order and bindings) while building a hashable shape key that uniquely determines the serialized HTML. Serialization, escaping, and eligibility validation run only on the first mount of each shape; every later mount of a structurally identical tree (for example, the rows of a list) is a dictionary hit.
Classes:
| Name | Description |
|---|---|
MountPlan |
Serialized mount plan for a static-skeleton VNode subtree. |
Functions:
| Name | Description |
|---|---|
build_plan |
Serialize |
MountPlan
¶
MountPlan(html: str, order: List[Tuple[int, VNode, Optional[VNode]]], bindings: List[Tuple[VNode, int, str, Any]])
Serialized mount plan for a static-skeleton VNode subtree.
Attributes:
| Name | Type | Description |
|---|---|---|
html |
The serialized HTML string for the skeleton. Static text content is hoisted (each text node appears as a single-space placeholder), so structurally-identical trees share the same string regardless of their text. |
|
order |
Pre-order list of |
|
bindings |
List of |
build_plan
¶
Serialize vnode's static structure, or return None when ineligible.
Eligible trees have an element root and contain only element/text
nodes plus dynamic placeholders (holes, fragments, components). The
VNode tree is normalized in place (children lists become VNode
lists) as a side effect, exactly as the per-node mount path does.
A single walk collects the per-instance order and bindings while building the shape key. The HTML string (and the eligibility verdict) comes from the shape cache; the full serializer runs only on the first mount of each shape.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
vnode
|
VNode
|
An element VNode (string tag, not |
required |
Returns:
| Type | Description |
|---|---|
Optional[MountPlan]
|
A |
What's in this module¶
template implements the template-based mounting fast path. When the
reconciler mounts a host-element subtree, it first asks build_plan to
serialize the static skeleton of the tree into a single HTML string
(with text content hoisted out). The skeleton is registered with the
rendering kernel once, parsed by the browser via a <template>
element, and every mount is a single clone op. The kernel walks the
clone in a deterministic pre-order, assigning a dense block of node
ids, so Python can address every node with no read-backs; text,
bindings, and dynamic children are then wired by id in the same
batched commit.
Hoisting text is what makes templates shared: a thousand list rows that differ only in their ids and labels serialize to the same skeleton, so the browser parses it once and clones it a thousand times, exactly like SolidJS's compiled templates.
How a plan is built¶
- Static tags, attributes, classes, styles, and datasets become part of the HTML string directly.
- Static text serializes as a one-space placeholder; the real value is
recorded as a
SET_TEXTbinding applied after the clone. - Reactive props (getter callables) are recorded as bindings; they're wrapped in per-prop effects after id assignment.
- Event handlers (
on_*) are recorded as bindings and registered through the kernel's delegated event system (LISTENops). value/checkedare recorded as DOM-property bindings and assigned post-clone, matching the per-node mount path exactly.- Dynamic children (holes, components, fragments) are serialized as comment placeholders; the reconciler mounts them at the placeholder position after id assignment.
When the fast path is skipped¶
build_plan refuses (and the reconciler falls back to per-node ops,
still batched in the same commit) when the subtree can't be
represented faithfully as HTML, for example: raw-text elements like
<script>, adjacent text nodes that would merge during parsing,
element nestings the parser rewrites (bare text in <table>,
auto-closed <p>, and similar), or environments whose DOM stub has no
<template> support. The fallback is purely a performance difference;
behavior is identical.
See also¶
- Concepts: Virtual DOM
reconciler: mounts plans and wires bindings.- Guides: Performance