-
-
Notifications
You must be signed in to change notification settings - Fork 4.2k
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
fix: improve performance of scheduling effects #13282
Conversation
🦋 Changeset detectedLatest commit: 9423767 The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
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 |
Does it makes sense to investigate avoiding the includes check and possibly even the walking up to the parents logic? I see that two usage sites first set the effect to dirty, then schedule it. Can we use a method in these places that does both, and bails early if we detect that the effect is already dirty? The |
@dummdidumm I looked into that, but we can't. I also tried doing a simple |
Are we saying that this only occurs inside benchmarks, and not inside real apps? If so, won't this make real apps slower for the sake of those benchmarks? |
@Rich-Harris It's definitely possible in real world applications that make use of |
Okay, I've removed the |
We call Though, going deeper: I don't really follow what the |
Yes we only bail out on branches. That's because they're not part of the reactive graph and thus cannot be made dirty from the reactive graph, so we use the MAYBE_DIRTY to flag that we need to visit them otherwise we skip them entirely in both
I can do that too. |
Right ready for review, I've made all the changes based off feedback. |
I actually feel pretty confident that this PR is a better direction than #13297. Writes are always more expensive than reads, and the less of them we have to do, the better. Ironically branch effects just happen to be a good place for that logic to exist IMO. |
flushSync(() => { | ||
map.delete(1); | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what's the purpose of these changes? they pass on main
already, so what are they testing exactly?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's because effect_root
didn't create a branch
before. Because child effects get attached to their parent after their contents run, the flushSync
doesn't do anything as the root has no child effects.
This very simple change has quite a significant impact on our local benchmark. In the case of some of the benchmarks, they're not wrapped in a branch effect, only a render effect. We now wrap them with a branch effect!