Description
Describe the bug
This will sound like a rather niche and inconsequential issue, but it relates to some of the current work around making hydration more efficient.
When you create a component with CSS custom properties...
<Foo --bar="baz" />
...the following JavaScript is generated:
$.css_props(node, true, () => ({ "--bar": "baz" }), ($$node) => Foo($$node, {}));
If the component is dynamic...
<svelte:component this={Foo} --bar="baz" />
...you get this:
$.component(node, () => Foo, ($$component) => {
$.css_props(node, true, () => ({ "--bar": "baz" }), ($$node) => $$component($$node, {}));
});
This is wrong. When the this
value changes, the $.component
effect re-runs, and the wrapper is destroyed and recreated. It should be this instead:
$.css_props(node, true, () => ({ "--bar": "baz" }), ($$node) => {
$.component(() => Foo, ($$component) => $$component($$node, {}));
});
(Note that the first argument to $.component
is removed, as it's actually unused.)
As things stand, this is mildly inefficient. But it goes from being inefficient to buggy if we change how hydration works — as in #11773, we really don't need to wrap the wrapper divs in <!--[-->...<!--]-->
markers or do unnecessary traversal with hydrate_anchor
; we can just pass the <div>
(which should probably be part of the $.template
call, along with any static properties — no need to create an effect unless we have dynamic properties) directly to $.css_props. If we do that today, the element is removed as soon as
this` changes, and the new one isn't created in the right place.
Reproduction
link (look at the JS output tab)
Logs
No response
System Info
next
Severity
annoyance