Skip to content

Conversation

@Rich-Harris
Copy link
Member

This fixes ones of the bugs identified in #17240 (comment). (To be honest I'm astonished that it lasted this long.) Specifically, when you have an each block go from ['a', 'b'] to [], and then to ['a'] while items are still outroing, b will never be removed from the DOM, because the a outro is aborted and the callback that destroys effects is never called.

This solution is admittedly a bit more involved than I initially hoped. I wonder if it would be better to coordinate effect destruction at the batch level, though I didn't pursue that as it would be a breaking change. At least this change imposes no costs on each blocks that don't contain outros.

Before submitting the PR, please make sure you do the following

  • It's really useful if your PR references an issue where it is discussed ahead of time. In many cases, features are absent for a reason. For large changes, please create an RFC: https://github.com/sveltejs/rfcs
  • Prefix your PR title with feat:, fix:, chore:, or docs:.
  • This message body should clearly illustrate what problems it solves.
  • Ideally, include a test that fails without this PR but passes with it.
  • If this PR changes code within packages/svelte/src, add a changeset (npx changeset).

Tests and linting

  • Run the tests with pnpm test and lint the project with pnpm lint

@changeset-bot
Copy link

changeset-bot bot commented Nov 27, 2025

🦋 Changeset detected

Latest commit: a64d391

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
svelte Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@github-actions
Copy link
Contributor

Playground

pnpm add https://pkg.pr.new/svelte@17258

@Rich-Harris Rich-Harris marked this pull request as draft November 27, 2025 02:32
@Rich-Harris
Copy link
Member Author

Marked as draft, because I'd like to fix the remaining issues as well if I can

@Rich-Harris Rich-Harris marked this pull request as ready for review December 3, 2025 05:36
@Rich-Harris
Copy link
Member Author

Alright, this turned into a far more comprehensive refactor. But we finally have an each block implementation that appears to pass the stress test:

The most obvious change in the diff is the outrogroups stuff, which coordinates the destruction of effects, fixing the bug described at the top of the thread. But arguably the more significant change is that we no longer maintain a separate linked list of items, parallel to the linked list of effects. This simplifies things quite a bit, and reduces both the memory cost of individual items, and the amount of work that needs to happen during reconciliation.

@Rich-Harris
Copy link
Member Author

Gah, spoke too soon. Found a case that fails the stress test. We're close, I can feel it — this branch gets way further into the test than anything else we've tried. Will come back to this tomorrow.

@Rich-Harris Rich-Harris marked this pull request as draft December 3, 2025 06:00
@Rich-Harris Rich-Harris marked this pull request as ready for review December 3, 2025 15:48
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I admit I don't fully understand all of this... but from my current level of understanding it looks good. I don't love having "yo please run this test if you feel like it" as part of our workflow though

Comment on lines +44 to +46
// When making substantive changes to this file, validate them with the each block stress test:
// https://svelte.dev/playground/1972b2cf46564476ad8c8c6405b23b7b
// This test also exists in this repo, as `packages/svelte/tests/manual/each-stress-test`

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't love this... is there a straightforward way we could automate stress testing when this file is changed?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm sure there's a way, but I'm not so sure about 'straightforward'. Even converting it to a test that could be part of our test suite would be difficult, I think

@Rich-Harris Rich-Harris merged commit 190e64a into main Dec 3, 2025
18 checks passed
@Rich-Harris Rich-Harris deleted the each-outros branch December 3, 2025 17:29
@github-actions github-actions bot mentioned this pull request Dec 3, 2025
@MathiasWP
Copy link
Contributor

MathiasWP commented Dec 4, 2025

I have no idea if this is a real error or not, but i clicked around on the stress test and the "failed to reconcile" error message showed up for two frames. It happens around the 14 second mark:

Screen.Recording.2025-12-04.at.13.16.41.mov

Screenshots of the frames:

Screenshot 2025-12-04 at 13 19 30 Screenshot 2025-12-04 at 13 19 05

@Rich-Harris
Copy link
Member Author

I suspect this is just cross-talk (ie pressing the button causes an update that the ongoing test doesn't expect)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants