chore: remove deopts and refactor code for controlled optimizations (#11040)

* chore: remove deopts and refactor code for controlled optimizations

* remove comment

* tune

* tweak

* tweak

* typo

* get rid of single-use variable

---------

Co-authored-by: Rich Harris <rich.harris@vercel.com>
pull/11043/head
Dominic Gannaway 8 months ago committed by GitHub
parent d85d5a060b
commit 3ece9cd051
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -17,8 +17,10 @@ import {
branch,
effect,
pause_effect,
get_out_transitions,
resume_effect,
pause_effects,
resume_effect
destroy_effects
} from '../../reactivity/effects.js';
import { source, mutable_source, set } from '../../reactivity/sources.js';
import { is_array, is_frozen, map_get, map_set } from '../../utils.js';
@ -244,11 +246,19 @@ function reconcile_indexed_array(array, state, anchor, render_fn, flags) {
effects.push(a_items[i].e);
}
pause_effects(effects, () => {
state.items.length = b;
var transitions = get_out_transitions(effects);
var items = state.items;
if (transitions.length === 0) {
destroy_effects(effects);
items.length = b;
} else {
pause_effects(effects, transitions, () => {
items.length = b;
});
}
}
}
/**
* Reconcile arrays by the equality of the elements in the array. This algorithm
@ -421,12 +431,17 @@ function reconcile_tracked_array(array, state, anchor, render_fn, flags, keys) {
});
}
// TODO: would be good to avoid this closure in the case where we have no
// transitions at all. It would make it far more JIT friendly in the hot cases.
pause_effects(to_destroy, () => {
var transitions = get_out_transitions(to_destroy);
if (transitions.length === 0) {
destroy_effects(to_destroy);
state.items = b_items;
} else {
pause_effects(to_destroy, transitions, () => {
state.items = b_items;
});
}
}
/**
* Longest Increased Subsequence algorithm

@ -313,23 +313,38 @@ export function pause_effect(effect, callback = noop) {
* Pause multiple effects simultaneously, and coordinate their
* subsequent destruction. Used in each blocks
* @param {import('#client').Effect[]} effects
* @param {() => void} callback
* @returns {import('#client').TransitionManager[]}
*/
export function pause_effects(effects, callback = noop) {
export function get_out_transitions(effects) {
/** @type {import('#client').TransitionManager[]} */
var transitions = [];
var length = effects.length;
for (var i = 0; i < length; i++) {
for (var i = 0; i < effects.length; i++) {
pause_children(effects[i], transitions, true);
}
// TODO: would be good to avoid this closure in the case where we have no
// transitions at all. It would make it far more JIT friendly in the hot cases.
out(transitions, () => {
for (var i = 0; i < length; i++) {
return transitions;
}
/**
* @param {import('#client').Effect[]} effects
*/
export function destroy_effects(effects) {
for (var i = 0; i < effects.length; i++) {
destroy_effect(effects[i]);
}
}
/**
* Pause multiple effects simultaneously, and coordinate their
* subsequent destruction. Used in each blocks
* @param {import('#client').Effect[]} effects
* @param {import('#client').TransitionManager[]} transitions
* @param {() => void} callback
*/
export function pause_effects(effects, transitions, callback = noop) {
out(transitions, () => {
destroy_effects(effects);
callback();
});
}
@ -370,13 +385,12 @@ function pause_children(effect, transitions, local) {
var child = effect.first;
while (child !== null) {
var sibling = child.next;
var transparent = (child.f & IS_ELSEIF) !== 0 || (child.f & BRANCH_EFFECT) !== 0;
// TODO we don't need to call pause_children recursively with a linked list in place
// it's slightly more involved though as we have to account for `transparent` changing
// through the tree.
pause_children(child, transitions, transparent ? local : false);
child = sibling;
child = child.next;
}
}

Loading…
Cancel
Save