-
-
Notifications
You must be signed in to change notification settings - Fork 4.7k
Description
Describe the bug
In a reactive declaration like this...
$: a = b(c);...Svelte correctly wraps the assignment to a in a call to $$invalidate. b and c are treated as dependents (assuming they are themselves reactive), resulting in the following code if c is reactive:
$$self.$$set = $$props => {
if ('c' in $$props) $$invalidate(1, c = $$props.c);
};
$$self.$$.update = () => {
if ($$self.$$.dirty & /*c*/ 2) {
$: $$invalidate(0, a = b(c));
}
};But if the assignment is destructured (and there are two or more destructured names)...
$: ({ x, y } = b(c));...something rather odd happens:
$$self.$$set = $$props => {
if ('b' in $$props) $$invalidate(2, b = $$props.b);
if ('c' in $$props) $$invalidate(3, c = $$props.c);
};
$$self.$$.update = () => {
if ($$self.$$.dirty & /*b, c*/ 12) {
$: $$invalidate(1, { x, y } = b(c), x, (($$invalidate(0, y), $$invalidate(2, b)), $$invalidate(3, c)));
}
};In this case x and y are correctly invalidated, but b and c are as well.
It's easy enough to work around — just don't use destructuring — but it's also a bit of a bad bug. In our case it caused a major performance headache as something intended to run rarely was instead attempting to run at 60fps (which in turn made it more like 10fps).
Reproduction
The simplest repro I've come up with is this one. This more involved one shows a reactive statement re-running unnecessarily as a result of the bug.
Logs
No response
System Info
System:
OS: macOS 10.15.7
CPU: (16) x64 Intel(R) Core(TM) i9-9980HK CPU @ 2.40GHz
Memory: 8.12 GB / 64.00 GB
Shell: 5.7.1 - /bin/zsh
Binaries:
Node: 16.5.0 - ~/.nvm/versions/node/v16.5.0/bin/node
Yarn: 1.22.5 - /usr/local/bin/yarn
npm: 7.19.1 - ~/.nvm/versions/node/v16.5.0/bin/npm
Browsers:
Chrome: 92.0.4515.107
Firefox: 90.0.1
Safari: 13.1.3
npmPackages:
svelte: ^3.38.2 => 3.38.2 (but note that it happens in 3.41.0, per the REPL)Severity
annoyance