diff --git a/.changeset/quick-paws-wash.md b/.changeset/quick-paws-wash.md new file mode 100644 index 0000000000..e93b68a0ca --- /dev/null +++ b/.changeset/quick-paws-wash.md @@ -0,0 +1,5 @@ +--- +'svelte': patch +--- + +feat: only traverse trailing static nodes during hydration diff --git a/packages/svelte/src/compiler/phases/3-transform/client/visitors/shared/fragment.js b/packages/svelte/src/compiler/phases/3-transform/client/visitors/shared/fragment.js index 6dcb794f2c..9251870c27 100644 --- a/packages/svelte/src/compiler/phases/3-transform/client/visitors/shared/fragment.js +++ b/packages/svelte/src/compiler/phases/3-transform/client/visitors/shared/fragment.js @@ -118,7 +118,7 @@ export function process_children(nodes, initial, is_element, { visit, state }) { // traverse to the last (n - 1) one when hydrating if (skipped > 1) { skipped -= 1; - state.init.push(b.stmt(get_node(false))); + state.init.push(b.stmt(b.call('$.next', skipped !== 1 && b.literal(skipped)))); } } diff --git a/packages/svelte/src/internal/client/dom/hydration.js b/packages/svelte/src/internal/client/dom/hydration.js index 62b40c8ccd..8523ff97d5 100644 --- a/packages/svelte/src/internal/client/dom/hydration.js +++ b/packages/svelte/src/internal/client/dom/hydration.js @@ -66,9 +66,16 @@ export function hydrate_template(template) { } } -export function next() { +export function next(count = 1) { if (hydrating) { - hydrate_next(); + var i = count; + var node = hydrate_node; + + while (i--) { + node = /** @type {TemplateNode} */ (get_next_sibling(node)); + } + + hydrate_node = node; } } diff --git a/packages/svelte/tests/snapshot/samples/skip-static-subtree/_expected/client/index.svelte.js b/packages/svelte/tests/snapshot/samples/skip-static-subtree/_expected/client/index.svelte.js index 4f59c4932e..76433ad5a7 100644 --- a/packages/svelte/tests/snapshot/samples/skip-static-subtree/_expected/client/index.svelte.js +++ b/packages/svelte/tests/snapshot/samples/skip-static-subtree/_expected/client/index.svelte.js @@ -1,7 +1,7 @@ import "svelte/internal/disclose-version"; import * as $ from "svelte/internal/client"; -var root = $.template(`

we don't need to traverse these nodes

or

these

ones

`, 3); +var root = $.template(`

we don't need to traverse these nodes

or

these

ones

these

trailing

nodes

can

be

completely

ignored

`, 3); 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); + $.next(14); $.reset(main); var cant_skip = $.sibling(main, 2); diff --git a/packages/svelte/tests/snapshot/samples/skip-static-subtree/_expected/server/index.svelte.js b/packages/svelte/tests/snapshot/samples/skip-static-subtree/_expected/server/index.svelte.js index 1018b5425e..2bd910508d 100644 --- a/packages/svelte/tests/snapshot/samples/skip-static-subtree/_expected/server/index.svelte.js +++ b/packages/svelte/tests/snapshot/samples/skip-static-subtree/_expected/server/index.svelte.js @@ -3,5 +3,5 @@ import * as $ from "svelte/internal/server"; export default function Skip_static_subtree($$payload, $$props) { let { title, content } = $$props; - $$payload.out += `

${$.escape(title)}

we don't need to traverse these nodes

or

these

ones

${$.html(content)}
`; + $$payload.out += `

${$.escape(title)}

we don't need to traverse these nodes

or

these

ones

${$.html(content)}

these

trailing

nodes

can

be

completely

ignored

`; } \ No newline at end of file diff --git a/packages/svelte/tests/snapshot/samples/skip-static-subtree/index.svelte b/packages/svelte/tests/snapshot/samples/skip-static-subtree/index.svelte index cc9d8172e6..de399169b4 100644 --- a/packages/svelte/tests/snapshot/samples/skip-static-subtree/index.svelte +++ b/packages/svelte/tests/snapshot/samples/skip-static-subtree/index.svelte @@ -18,6 +18,13 @@

these

ones

{@html content} +

these

+

trailing

+

nodes

+

can

+

be

+

completely

+

ignored