-
-
Notifications
You must be signed in to change notification settings - Fork 4.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Infinite loop when binding to an item in a for loop #7752
Comments
Could you put this into a REPL (https://svelte.dev/repl/hello-world)? This is a great way to share small Svelte applications to demonstrate bugs like this. If it actually causes 100% CPU, maybe comment out the part you've identified as being the problem and give instructions in the REPL à la "Uncomment this part to cause 100% CPU". Edit: fwiw, you entire <nav-el bind:this={route.div} class:tab-active={path === window.location.pathname}>{route.name}</nav-el> Which would also later make it much easier to use a client side router. Because it would be reactive. Right now |
I, unfortunately, cannot put it into a REPL, because of #6900 which doesn't allow to declare TypeScript classes inside a <script> block. Thanks for the idea of squashing it into one line, I probably won't need the bind:this={route.div} at all, but it would still be nice to figure it out. EDIT: Your one-liner doesn't appear to work, because window is not defined. |
Does it not repro with JavaScript? I'm sure you can turn 10 lines of TypeScript into JavaScript?
Please provide a REPL if possible. Works for me https://svelte.dev/repl/f400f9f6692e4193b81a0c6e7b6f5244?version=3.49.0 |
After some trial and error (I've never touched JavaScript, only TS) I've converted the original to this REPL: As far as your one-liner goes, you are right that it works in REPL: https://svelte.dev/repl/7c3ac2ac4e4546be8e9d3a10f6d8f768?version=3 However, it does not work in my SvelteKit application when I access it via npm run dev. It throws the following error:
|
Thanks! I'm sure someone can use that to further debug the issue.
You never mentioned SvelteKit, |
Sorry, I thought that it was unrelated to the original issue, do you have any idea how to transform this one-liner to sveltekit? |
SvelteKit offers a whole host of information for this precise purpose. E.g. https://kit.svelte.dev/docs/modules#$app-stores-page allows you to access the current URL on both server and client. If you follow the Getting Started https://kit.svelte.dev/docs/introduction#getting-started you can see that in the demo app: <nav>
<svg viewBox="0 0 2 3" aria-hidden="true">
<path d="M0,0 L1,2 C1.5,3 1.5,3 2,3 L2,0 Z" />
</svg>
<ul>
<li class:active={$page.url.pathname === '/'}><a sveltekit:prefetch href="/">Home</a></li>
<li class:active={$page.url.pathname === '/about'}>
<a sveltekit:prefetch href="/about">About</a>
</li>
<li class:active={$page.url.pathname === '/todos'}>
<a sveltekit:prefetch href="/todos">Todos</a>
</li>
</ul>
<svg viewBox="0 0 2 3" aria-hidden="true">
<path d="M0,0 L0,3 C0.5,3 0.5,3 1,2 L2,0 Z" />
</svg>
</nav> Edit: I recommend checking out the demo app before working with an empty project. |
I was able to track this down to the use of the spread operator. Or more specifically cloning the array, https://svelte.dev/repl/d8f6f4532ab04a1fa028d1835d55839e?version=3.49.0 The first two each cause infinite loops, the third does not. |
Here's the only difference between the generated Svelte code. This would be the time someone who knows about Svelte internals should take over. --- good.js 2022-08-05 16:16:24.071516677 +0200
+++ bad.js 2022-08-05 16:15:57.823234520 +0200
@@ -20,7 +20,7 @@
return child_ctx;
}
-// (19:0) {#each bindings as binding}
+// (7:0) {#each [...bindings] as binding}
function create_each_block(ctx) {
let div;
let each_value = /*each_value*/ ctx[3];
@@ -56,7 +56,7 @@
function create_fragment(ctx) {
let each_1_anchor;
- let each_value = /*bindings*/ ctx[0];
+ let each_value = [.../*bindings*/ ctx[0]];
let each_blocks = [];
for (let i = 0; i < each_value.length; i += 1) {
@@ -80,7 +80,7 @@
},
p(ctx, [dirty]) {
if (dirty & /*bindings*/ 1) {
- each_value = /*bindings*/ ctx[0];
+ each_value = [.../*bindings*/ ctx[0]];
let i;
for (i = 0; i < each_value.length; i += 1) {
|
I think this could potentially be yet another version of #5689. Where the first iteration will correctly invalidate the entire |
However, if I understand correctly, #5689 is a duplicate to #4447, which should be fixed. |
I've been triaging Svelte issues for well over a year now and seen every single issue and this comes up regularly, it is definitely not fixed (at least not every variation of it). I even ran into it myself over year ago #6298 To make this very clear, here is a REPL https://svelte.dev/repl/5f436e05809346a38baf906184321761?version=3.49.0 |
Looked at this a bit closer and the cause for the loop is:
I'm not sure how this can be solved in a way that breaks the loop and at the same time plays it safe in other use cases. |
I don't know how this is implemented, but why is bind this involved with the array at all? (I assume some optimization?) It should only care about its expression, which for |
My assumption is that the array instance is checked because a different instance hints at needing to do the binding work again. I'm not sure what it would mean to check the array entry instead, i.e. if there would be missed updates people expect in other places. |
This is fixed in Svelte 5, because dependencies are tracked at runtime and the infinite loop is thus avoided |
Describe the bug
The page freezes when I attempt to iterate through a map containing a class and bind a freshly created element using data from that class into a field of that class. This appears to be related to #6921
Considering that one of my cores spikes up to 100%, there is probably some infinite loop going on.
I am a beginner, so I am sorry if I am making some rookie mistake
Reproduction
I have this example:
NavbarRoute:
By commenting out some parts of the code, I've found out, that it hangs due to:
bind:this={route.div}
Logs
Nothing showed up in the server and browser logs.
System Info
System: OS: Linux 5.18 Arch Linux CPU: (24) x64 AMD Ryzen 9 5900X 12-Core Processor Memory: 44.10 GB / 62.71 GB Container: Yes Shell: 5.1.16 - /bin/bash Binaries: Node: 16.16.0 - /usr/bin/node Yarn: 1.22.19 - /usr/bin/yarn npm: 8.15.1 - /usr/bin/npm Browsers: Chromium: 104.0.5112.79 Firefox: 103.0.1 npmPackages: svelte: ^3.44.0 => 3.49.0
Severity
blocking all usage of svelte
The text was updated successfully, but these errors were encountered: