mirror of https://github.com/sveltejs/svelte
fix: merge consecutive text nodes during hydration for large text content (#17587)
* fix: merge consecutive text nodes during hydration for large text content Fixes #17582 Browsers automatically split text nodes exceeding 65536 characters into multiple consecutive text nodes during HTML parsing. This causes hydration mismatches when Svelte expects a single text node. The fix merges consecutive text nodes during hydration by: - Detecting when the current node is a text node - Finding all consecutive text node siblings - Merging their content into the first text node - Removing the extra text nodes This restores correct hydration behavior for large text content. * add test, fix * fix * fix * changeset --------- Co-authored-by: Miner <miner@example.com> Co-authored-by: Rich Harris <rich.harris@vercel.com>pull/17585/head
parent
ebe583f2bb
commit
8933653fbe
@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
'svelte': patch
|
||||||
|
---
|
||||||
|
|
||||||
|
fix: merge consecutive large text nodes
|
||||||
@ -0,0 +1,24 @@
|
|||||||
|
import { test } from '../../assert';
|
||||||
|
|
||||||
|
// Browsers split text nodes > 65536 characters into multiple consecutive text nodes
|
||||||
|
// during HTML parsing. This test verifies that hydration correctly merges them.
|
||||||
|
const LARGE_TEXT = 'x'.repeat(70000);
|
||||||
|
|
||||||
|
export default test({
|
||||||
|
mode: ['hydrate'],
|
||||||
|
skip_mode: ['client'],
|
||||||
|
|
||||||
|
props: {
|
||||||
|
text: LARGE_TEXT
|
||||||
|
},
|
||||||
|
|
||||||
|
async test({ assert, target }) {
|
||||||
|
const [p] = target.querySelectorAll('p');
|
||||||
|
|
||||||
|
// The text content should be preserved after hydration
|
||||||
|
assert.equal(p.textContent?.trim(), LARGE_TEXT);
|
||||||
|
// After hydration, there should be only one text node (plus possible comment nodes)
|
||||||
|
const textNodes = [...p.childNodes].filter((node) => node.nodeType === 3);
|
||||||
|
assert.equal(textNodes.length, 1, `Expected 1 text node, got ${textNodes.length}`);
|
||||||
|
}
|
||||||
|
});
|
||||||
@ -0,0 +1,5 @@
|
|||||||
|
<script>
|
||||||
|
let { text } = $props();
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<p>{text}</p>
|
||||||
Loading…
Reference in new issue