Skip to content

Conversation

@Rich-Harris
Copy link
Member

@Rich-Harris Rich-Harris commented Nov 3, 2025

This makes good on my threat in #17102 (comment) to sort out all the convoluted nonsense around UNOWNED and DISCONNECTED deriveds. We've made this far more complicated than it needs to be. All we need to do is push the current signal to its dependencies' reactions when the signal is connected to the graph, and skip doing so when it isn't.

Most benchmarks are unaffected, but where there is a significant effect, this branch is much faster.

results of `pnpm bench:compare`
sbench_create_signals
  time: fastest is a (remove-unowned)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 367.63ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 373.89ms
  gc_time: fastest is a (remove-unowned)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 160.79ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 164.47ms
sbench_create_0to1
  time: fastest is b (main)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 6.16ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼  5.93ms
sbench_create_1to1
  time: fastest is b (main)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 21.26ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 21.05ms
  gc_time: fastest is b (main)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 3.02ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 2.96ms
sbench_create_2to1
  time: fastest is b (main)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 18.48ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 18.42ms
  gc_time: fastest is a (remove-unowned)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼  2.92ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 3.00ms
sbench_create_4to1
  time: fastest is b (main)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 17.03ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 16.77ms
  gc_time: fastest is b (main)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 3.01ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 2.97ms
sbench_create_1000to1
  time: fastest is a (remove-unowned)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 14.87ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 14.95ms
  gc_time: fastest is a (remove-unowned)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 2.85ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 2.91ms
sbench_create_1to2
  time: fastest is b (main)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 10.63ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 10.59ms
  gc_time: fastest is b (main)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 0.77ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼   0.71ms
sbench_create_1to4
  time: fastest is a (remove-unowned)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 8.72ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 8.82ms
  gc_time: fastest is a (remove-unowned)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼  0.51ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 0.54ms
sbench_create_1to8
  time: fastest is b (main)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 7.42ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼  7.21ms
sbench_create_1to1000
  time: fastest is b (main)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 8.60ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 8.57ms
  gc_time: fastest is a (remove-unowned)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼  0.63ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 0.67ms
kairo_avoidable_owned
  time: fastest is b (main)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 513.85ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 511.03ms
  gc_time: fastest is a (remove-unowned)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼  36.68ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 38.50ms
kairo_avoidable_unowned
  time: fastest is a (remove-unowned)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼     499.87ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 612.69ms
  gc_time: fastest is a (remove-unowned)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼  36.09ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 38.70ms
kairo_broad_owned
  time: fastest is b (main)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 501.31ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 499.64ms
  gc_time: fastest is b (main)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 4.13ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼   3.68ms
kairo_broad_unowned
  time: fastest is b (main)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 499.73ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 498.98ms
  gc_time: fastest is b (main)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 4.11ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼   3.71ms
kairo_deep_owned
  time: fastest is b (main)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 218.20ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 214.63ms
  gc_time: fastest is b (main)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 2.82ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 2.78ms
kairo_deep_unowned
  time: fastest is a (remove-unowned)
    a: ◼◼◼◼                 212.50ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 1011.22ms
  gc_time: fastest is a (remove-unowned)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼      2.86ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 3.75ms
kairo_diamond_owned
  time: fastest is a (remove-unowned)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 418.69ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 421.05ms
  gc_time: fastest is b (main)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 22.13ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 22.09ms
kairo_diamond_unowned
  time: fastest is a (remove-unowned)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼    409.05ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 495.23ms
  gc_time: fastest is a (remove-unowned)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼  21.79ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 22.39ms
kairo_triangle_owned
  time: fastest is a (remove-unowned)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 127.22ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 130.11ms
  gc_time: fastest is a (remove-unowned)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼  4.06ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 4.18ms
kairo_triangle_unowned
  time: fastest is a (remove-unowned)
    a: ◼◼◼◼◼◼◼◼◼◼           123.38ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 246.39ms
  gc_time: fastest is b (main)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 4.36ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼  4.05ms
kairo_mux_owned
  time: fastest is a (remove-unowned)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼  328.77ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 345.10ms
  gc_time: fastest is b (main)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 2.90ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 2.87ms
kairo_mux_unowned
  time: fastest is a (remove-unowned)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼        326.24ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 494.95ms
  gc_time: fastest is b (main)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 3.10ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼  3.01ms
kairo_repeated_owned
  time: fastest is b (main)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 80.15ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 79.85ms
  gc_time: fastest is a (remove-unowned)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼   2.95ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 3.28ms
kairo_repeated_unowned
  time: fastest is a (remove-unowned)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼  75.69ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 78.93ms
  gc_time: fastest is b (main)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 3.53ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼   3.20ms
kairo_unstable_owned
  time: fastest is b (main)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 120.92ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼  117.36ms
  gc_time: fastest is b (main)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 3.95ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼  3.84ms
kairo_unstable_unowned
  time: fastest is a (remove-unowned)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼   118.29ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 133.75ms
  gc_time: fastest is b (main)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 3.98ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 3.90ms
mol_bench_owned
  time: fastest is b (main)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 286.63ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 285.10ms
  gc_time: fastest is a (remove-unowned)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 0.93ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 0.94ms
mol_bench_unowned
  time: fastest is a (remove-unowned)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼  286.43ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 304.27ms
  gc_time: fastest is a (remove-unowned)
    a: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼    1.01ms
    b: ◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼ 1.17ms

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 3, 2025

🦋 Changeset detected

Latest commit: 1032b31

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

github-actions bot commented Nov 3, 2025

Playground

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

Copy link
Member

@dummdidumm dummdidumm left a comment

Choose a reason for hiding this comment

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

This looks promising - what I don't quite understand at the moment is how it's safe that something counts as owned as long as it has any reactions

@Rich-Harris
Copy link
Member Author

There is no concept of ownership any more — something is either connected (in which case it will be notified of changes to its dependencies, and will in turn notify its dependents) or it isn't. We don't need to care if a derived is owned or not

@Rich-Harris Rich-Harris marked this pull request as ready for review November 4, 2025 14:24
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.

3 participants