feat: omit trailing `$.sibling` calls where possible

omit-trailing-sibling-calls
Rich Harris 7 months ago
parent 8aed27db97
commit 548a6a7a98

@ -147,7 +147,7 @@ export function Fragment(node, context) {
// special case — we can use `$.text` instead of creating a unique template
const id = b.id(context.state.scope.generate('text'));
process_children(trimmed, () => id, false, {
process_children(trimmed, () => id, false, false, {
...context,
state
});
@ -157,12 +157,12 @@ export function Fragment(node, context) {
} else {
if (is_standalone) {
// no need to create a template, we can just use the existing block's anchor
process_children(trimmed, () => b.id('$$anchor'), false, { ...context, state });
process_children(trimmed, () => b.id('$$anchor'), false, false, { ...context, state });
} else {
/** @type {(is_text: boolean) => Expression} */
const expression = (is_text) => b.call('$.first_child', id, is_text && b.true);
process_children(trimmed, expression, false, { ...context, state });
process_children(trimmed, expression, false, false, { ...context, state });
let flags = TEMPLATE_FRAGMENT;

@ -340,7 +340,7 @@ export function RegularElement(node, context) {
arg = b.member(arg, 'content');
}
process_children(trimmed, () => b.call('$.child', arg), true, {
process_children(trimmed, () => b.call('$.child', arg), true, needs_reset, {
...context,
state: child_state
});

@ -11,10 +11,11 @@ import { build_template_literal, build_update } from './utils.js';
* corresponding template node references these updates are applied to.
* @param {SvelteNode[]} nodes
* @param {(is_text: boolean) => Expression} initial
* @param {boolean} is_element
* @param {boolean} is_element TODO get rid of this we should be able to determine controlled status during analysis
* @param {boolean} needs_reset
* @param {ComponentContext} context
*/
export function process_children(nodes, initial, is_element, { visit, state }) {
export function process_children(nodes, initial, is_element, needs_reset, { visit, state }) {
const within_bound_contenteditable = state.metadata.bound_contenteditable;
let prev = initial;
let skipped = 0;
@ -116,7 +117,7 @@ export function process_children(nodes, initial, is_element, { visit, state }) {
// if there are trailing static text nodes/elements,
// traverse to the last (n - 1) one when hydrating
if (skipped > 1) {
if (skipped > 1 && !needs_reset) {
skipped -= 1;
state.init.push(b.stmt(get_node(false)));
}

@ -1,7 +1,7 @@
import "svelte/internal/disclose-version";
import * as $ from "svelte/internal/client";
var root = $.template(`<header><nav><a href="/">Home</a> <a href="/away">Away</a></nav></header> <main><h1> </h1> <div class="static"><p>we don't need to traverse these nodes</p></div> <p>or</p> <p>these</p> <p>ones</p> <!></main>`, 1);
var root = $.template(`<header><nav><a href="/">Home</a> <a href="/away">Away</a></nav></header> <main><h1> </h1> <div class="static"><p>we don't need to traverse these nodes</p></div> <p>or</p> <p>these</p> <p>ones</p> <!> <p>these</p> <p>trailing</p> <p>nodes</p> <p>can</p> <p>be</p> <p>completely</p> <p>ignored</p></main>`, 1);
export default function Skip_static_subtree($$anchor, $$props) {
var fragment = root();
@ -14,6 +14,7 @@ export default function Skip_static_subtree($$anchor, $$props) {
var node = $.sibling(h1, 10);
$.html(node, () => $$props.content, false, false);
$.sibling(node, 14);
$.reset(main);
$.template_effect(() => $.set_text(text, $$props.title));
$.append($$anchor, fragment);

@ -3,5 +3,5 @@ import * as $ from "svelte/internal/server";
export default function Skip_static_subtree($$payload, $$props) {
let { title, content } = $$props;
$$payload.out += `<header><nav><a href="/">Home</a> <a href="/away">Away</a></nav></header> <main><h1>${$.escape(title)}</h1> <div class="static"><p>we don't need to traverse these nodes</p></div> <p>or</p> <p>these</p> <p>ones</p> ${$.html(content)}</main>`;
$$payload.out += `<header><nav><a href="/">Home</a> <a href="/away">Away</a></nav></header> <main><h1>${$.escape(title)}</h1> <div class="static"><p>we don't need to traverse these nodes</p></div> <p>or</p> <p>these</p> <p>ones</p> ${$.html(content)} <p>these</p> <p>trailing</p> <p>nodes</p> <p>can</p> <p>be</p> <p>completely</p> <p>ignored</p></main>`;
}

@ -18,4 +18,11 @@
<p>these</p>
<p>ones</p>
{@html content}
<p>these</p>
<p>trailing</p>
<p>nodes</p>
<p>can</p>
<p>be</p>
<p>completely</p>
<p>ignored</p>
</main>

Loading…
Cancel
Save