-
-
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
fix invalidate while update #4101
fix invalidate while update #4101
Conversation
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.
I think it's much more appropriate to make changes to the way we handle action callbacks, since that is the only place that we've seen invalidates get lost.
This PR is more of a "salt-the-earth" approach that could have serious performance impacts.
I'll mock up an example of the generated code I had in mind so we all can discuss further on Discord and figure out how to convince the compiler to do what we need.
@@ -73,8 +73,9 @@ function update($$) { | |||
if ($$.fragment !== null) { | |||
$$.update(); | |||
run_all($$.before_update); | |||
$$.fragment && $$.fragment.p($$.ctx, $$.dirty); | |||
const dirty = $$.dirty; | |||
$$.dirty = [-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.
This will cause update to refresh everything, whether changed or not.
Also, we need to be sure that the action callback is only triggered once.
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.
I thought of another oops... what if the 32nd element is invalidated?
We'd lose the bit since the special [-1]
is not handled inside p
.
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.
only have 31 bit per item in the array, if i understand correctly,
https://github.com/sveltejs/svelte/blob/master/src/compiler/compile/render_dom/Renderer.ts#L216-L217
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.
I think I'm losing it because I thought I saw the fragment update called twice but it is only once.... so nevermind, you are absolutely correct here.
Since this change exists in the other PR, we should close this out.
understand your concern. |
Can we safely revert the changes in #4095 as part of this? I'd like to be able to bring back destructuring whenever possible. As for whether actions are the only place we need to worry about: I'd like to hear what Rich thinks about that - but, since he thought there was no way updates could invalidate additional things, it makes sense to assume that this is the only one unless we bump into another one in the future. |
yes. @Conduitry reverted in a separate PR #4102 to keep this one clean, to show what's changed. |
actually i feel this change is quite safe and clean. if there's no if there is, it should be thought of the update in the next update cycle, which makes things cleaner to think about, ie |
Sorry to post such a large counter-example, but... Given this Svelte code:
Will result in this being generated for p (ignore the dev stuff):
Your change will have the side effect of calling the action twice in the same update cycle. Now, let's say I add 31 more variables, the code becomes:
Your change will now cause every one of them to be refreshed in the DOM, even though only |
Here's my idea, although not perfectly efficient because it re-updates anything that had a bitmask set initially. It can be improved by taking a snapshot as previous suggested and masking off the bits already taken care of just before calling the actions. We wouldn't have to track a weight Caveat: Given this Svelte code:
Generate this:
...and this...
|
oh i roughly understand your concern now. yes, -1 is svelte/src/runtime/internal/Component.ts Lines 90 to 93 in 54e8037
|
Yeah, I see in #4102, you save off dirty, set the component dirty to the special case, and then call update with the saved mask. Let me try that branch on my test cases here and see what happens (which I'm sure you already did). EDIT: Great work!!! |
Fix #4098
the dirty bitmask passed into the
p
function will be a snapshot of the dirty accumulated so far.reset the dirty bitmask before running
p
function, any$$invalidate
call within thep
function will schedule another update function.