You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Currently compiling a component emits a lot of boring DOM mutation logic. For example, even the simple svelte.dev/repl hello world example (when hydration is enabled) emits:
The context variable ctx would allow abstracting away the normal create/mount mode (i.e., appending to target before anchor) or in rehydrate's claim/mount mode (i.e., appending to target, but trying to reuse its existing children).
The convention would be nodes would be immediately inserted into the DOM in the order they're constructed, so there's no separate append calls necessary. Also, in rehydrate mode, it would prefer claiming existing nodes if possible and any leftover unclaimed nodes would be automatically detached, so there's no need for the h1_nodes.forEach(detach); call. Finally, because the text nodes are automatically appended to the DOM, there's no need to save them as t0/t1/t2 anymore. (h1 still needs to be saved to implement detach.)
For example, when compiling without rehydration support, element and text might be implemented something like:
function construct(fn, target, anchor) {
const ctx = [target, archor];
fn(ctx);
}
function emit(ctx, node) {
const [target, anchor] = ctx;
target.appendChild(node, anchor);
}
function element(ctx, name, attributes, children) {
const node = document.createElement(name);
set_attributes(node, attributes);
construct(children, node); // Recursively construct children with new context
emit(ctx, node);
}
function text(ctx, data) {
emit(ctx, document.createTextNode(data));
}
Alternatively, by simply tweaking construct and emit, we could defer DOM operations until all of a node's children have been constructed (i.e., more like the current separation of create/mount):
function construct(fn, target, anchor) {
const ctx = [];
fn(ctx);
for (let child of ctx) {
target.appendChild(child, anchor);
}
}
function emit(ctx, node) {
ctx.push(node);
}
Edit: Or using document fragments:
function construct(fn, target, archor) {
const ctx = document.createDocumentFragment();
fn(ctx);
target.appendChild(ctx, anchor);
}
function emit(ctx, node) {
ctx.appendChild(node);
}
I plan on experimenting with the feasibility of this approach and its impact on JS bundle size.
My main question is whether there's a need for the current separation between node construction and mounting. E.g., is it needed for animation or something? As far as I can tell, it doesn't seem needed.
Filing an issue to describe the idea in case anyone has feedback on it (e.g., further room for improvement, or issues I'm overlooking that might prevent this approach from working at all).
The text was updated successfully, but these errors were encountered:
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.
Currently compiling a component emits a lot of boring DOM mutation logic. For example, even the simple svelte.dev/repl hello world example (when hydration is enabled) emits:
I think this could instead be compiled as something like:
The context variable
ctx
would allow abstracting away the normal create/mount mode (i.e., appending totarget
beforeanchor
) or in rehydrate's claim/mount mode (i.e., appending totarget
, but trying to reuse its existing children).The convention would be nodes would be immediately inserted into the DOM in the order they're constructed, so there's no separate
append
calls necessary. Also, in rehydrate mode, it would prefer claiming existing nodes if possible and any leftover unclaimed nodes would be automatically detached, so there's no need for theh1_nodes.forEach(detach);
call. Finally, because the text nodes are automatically appended to the DOM, there's no need to save them as t0/t1/t2 anymore. (h1 still needs to be saved to implementdetach
.)For example, when compiling without rehydration support,
element
andtext
might be implemented something like:Alternatively, by simply tweaking
construct
andemit
, we could defer DOM operations until all of a node's children have been constructed (i.e., more like the current separation of create/mount):Edit: Or using document fragments:
I plan on experimenting with the feasibility of this approach and its impact on JS bundle size.
My main question is whether there's a need for the current separation between node construction and mounting. E.g., is it needed for animation or something? As far as I can tell, it doesn't seem needed.
Filing an issue to describe the idea in case anyone has feedback on it (e.g., further room for improvement, or issues I'm overlooking that might prevent this approach from working at all).
The text was updated successfully, but these errors were encountered: