Skip to content

Commit bd2a586

Browse files
authored
chore: more transition code-golfing (#9536)
1 parent 699c337 commit bd2a586

File tree

5 files changed

+93
-76
lines changed

5 files changed

+93
-76
lines changed

.changeset/kind-deers-lay.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'svelte': patch
3+
---
4+
5+
chore: more transition code-golfing

packages/svelte/src/internal/client/block.js

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,14 @@ export function create_root_block(intro) {
3535
/** @returns {import('./types.js').IfBlock} */
3636
export function create_if_block() {
3737
return {
38-
// current
39-
c: false,
38+
// alternate transitions
39+
a: null,
40+
// alternate effect
41+
ae: null,
42+
// consequent transitions
43+
c: null,
44+
// consequent effect
45+
ce: null,
4046
// dom
4147
d: null,
4248
// effect
@@ -46,7 +52,9 @@ export function create_if_block() {
4652
// transition
4753
r: null,
4854
// type
49-
t: IF_BLOCK
55+
t: IF_BLOCK,
56+
// value
57+
v: false
5058
};
5159
}
5260

packages/svelte/src/internal/client/render.js

Lines changed: 13 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ import {
7070
} from './hydration.js';
7171
import { array_from, define_property, get_descriptor, get_descriptors, is_array } from './utils.js';
7272
import { is_promise } from '../common.js';
73-
import { bind_transition, remove_in_transitions, trigger_transitions } from './transitions.js';
73+
import { bind_transition, trigger_transitions } from './transitions.js';
7474

7575
/** @type {Set<string>} */
7676
const all_registerd_events = new Set();
@@ -1355,8 +1355,6 @@ export function slot(anchor_node, slot_fn, slot_props, fallback_fn) {
13551355
function if_block(anchor_node, condition_fn, consequent_fn, alternate_fn) {
13561356
const block = create_if_block();
13571357
hydrate_block_anchor(anchor_node);
1358-
const consequent_transitions = new Set();
1359-
const alternate_transitions = new Set();
13601358
const previous_hydration_fragment = current_hydration_fragment;
13611359

13621360
/** @type {null | import('./types.js').TemplateNode | Array<import('./types.js').TemplateNode>} */
@@ -1366,59 +1364,32 @@ function if_block(anchor_node, condition_fn, consequent_fn, alternate_fn) {
13661364
let has_mounted = false;
13671365
let has_mounted_branch = false;
13681366

1369-
block.r =
1370-
/**
1371-
* @param {import('./types.js').Transition} transition
1372-
* @returns {void}
1373-
*/
1374-
(transition) => {
1375-
// block.current
1376-
if (block.c) {
1377-
consequent_transitions.add(transition);
1378-
transition.f(() => {
1379-
consequent_transitions.delete(transition);
1380-
remove_in_transitions(consequent_transitions);
1381-
if (consequent_transitions.size === 0) {
1382-
execute_effect(consequent_effect);
1383-
}
1384-
});
1385-
} else {
1386-
alternate_transitions.add(transition);
1387-
transition.f(() => {
1388-
alternate_transitions.delete(transition);
1389-
remove_in_transitions(alternate_transitions);
1390-
if (alternate_transitions.size === 0) {
1391-
execute_effect(alternate_effect);
1392-
}
1393-
});
1394-
}
1395-
};
13961367
const if_effect = render_effect(
13971368
() => {
13981369
const result = !!condition_fn();
1399-
if (block.c !== result || !has_mounted) {
1400-
block.c = result;
1370+
if (block.v !== result || !has_mounted) {
1371+
block.v = result;
14011372
if (has_mounted) {
1373+
const consequent_transitions = block.c;
1374+
const alternate_transitions = block.a;
14021375
if (result) {
1403-
remove_in_transitions(alternate_transitions);
1404-
if (alternate_transitions.size === 0) {
1376+
if (alternate_transitions === null || alternate_transitions.size === 0) {
14051377
execute_effect(alternate_effect);
14061378
} else {
14071379
trigger_transitions(alternate_transitions, 'out');
14081380
}
1409-
if (consequent_transitions.size === 0) {
1381+
if (consequent_transitions === null || consequent_transitions.size === 0) {
14101382
execute_effect(consequent_effect);
14111383
} else {
14121384
trigger_transitions(consequent_transitions, 'in');
14131385
}
14141386
} else {
1415-
remove_in_transitions(consequent_transitions);
1416-
if (consequent_transitions.size === 0) {
1387+
if (consequent_transitions === null || consequent_transitions.size === 0) {
14171388
execute_effect(consequent_effect);
14181389
} else {
14191390
trigger_transitions(consequent_transitions, 'out');
14201391
}
1421-
if (alternate_transitions.size === 0) {
1392+
if (alternate_transitions === null || alternate_transitions.size === 0) {
14221393
execute_effect(alternate_effect);
14231394
} else {
14241395
trigger_transitions(alternate_transitions, 'in');
@@ -1455,7 +1426,7 @@ function if_block(anchor_node, condition_fn, consequent_fn, alternate_fn) {
14551426
remove(consequent_dom);
14561427
consequent_dom = null;
14571428
}
1458-
if (block.c) {
1429+
if (block.v) {
14591430
consequent_fn(anchor_node);
14601431
if (!has_mounted_branch) {
14611432
// Restore previous fragment so that Svelte continues to operate in hydration mode
@@ -1469,14 +1440,15 @@ function if_block(anchor_node, condition_fn, consequent_fn, alternate_fn) {
14691440
block,
14701441
true
14711442
);
1443+
block.ce = consequent_effect;
14721444
// Managed effect
14731445
const alternate_effect = render_effect(
14741446
() => {
14751447
if (alternate_dom !== null) {
14761448
remove(alternate_dom);
14771449
alternate_dom = null;
14781450
}
1479-
if (!block.c) {
1451+
if (!block.v) {
14801452
if (alternate_fn !== null) {
14811453
alternate_fn(anchor_node);
14821454
}
@@ -1492,6 +1464,7 @@ function if_block(anchor_node, condition_fn, consequent_fn, alternate_fn) {
14921464
block,
14931465
true
14941466
);
1467+
block.ae = alternate_effect;
14951468
push_destroy_fn(if_effect, () => {
14961469
if (consequent_dom !== null) {
14971470
remove(consequent_dom);
@@ -1676,7 +1649,6 @@ export function component(anchor_node, component_fn, render_fn) {
16761649
transitions.add(transition);
16771650
transition.f(() => {
16781651
transitions.delete(transition);
1679-
remove_in_transitions(transitions);
16801652
if (transitions.size === 0) {
16811653
if (render.e !== null) {
16821654
if (render.d !== null) {
@@ -1724,7 +1696,6 @@ export function component(anchor_node, component_fn, render_fn) {
17241696
return;
17251697
}
17261698
const transitions = render.s;
1727-
remove_in_transitions(transitions);
17281699
if (transitions.size === 0) {
17291700
if (render.d !== null) {
17301701
remove(render.d);
@@ -1804,7 +1775,6 @@ function await_block(anchor_node, input, pending_fn, then_fn, catch_fn) {
18041775
transitions.add(transition);
18051776
transition.f(() => {
18061777
transitions.delete(transition);
1807-
remove_in_transitions(transitions);
18081778
if (transitions.size === 0) {
18091779
if (render.e !== null) {
18101780
if (render.d !== null) {
@@ -1861,7 +1831,6 @@ function await_block(anchor_node, input, pending_fn, then_fn, catch_fn) {
18611831
return;
18621832
}
18631833
const transitions = render.s;
1864-
remove_in_transitions(transitions);
18651834
if (transitions.size === 0) {
18661835
if (render.d !== null) {
18671836
remove(render.d);
@@ -1966,7 +1935,6 @@ export function key(anchor_node, key, render_fn) {
19661935
transitions.add(transition);
19671936
transition.f(() => {
19681937
transitions.delete(transition);
1969-
remove_in_transitions(transitions);
19701938
if (transitions.size === 0) {
19711939
if (render.e !== null) {
19721940
if (render.d !== null) {
@@ -2007,7 +1975,6 @@ export function key(anchor_node, key, render_fn) {
20071975
return;
20081976
}
20091977
const transitions = render.s;
2010-
remove_in_transitions(transitions);
20111978
if (transitions.size === 0) {
20121979
if (render.d !== null) {
20131980
remove(render.d);
@@ -2195,7 +2162,6 @@ function each(anchor_node, collection, flags, key_fn, render_fn, fallback_fn, re
21952162
transitions.add(transition);
21962163
transition.f(() => {
21972164
transitions.delete(transition);
2198-
remove_in_transitions(transitions);
21992165
if (transitions.size === 0) {
22002166
if (fallback.e !== null) {
22012167
if (fallback.d !== null) {

packages/svelte/src/internal/client/transitions.js

Lines changed: 52 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import {
1515
current_effect,
1616
destroy_signal,
1717
effect,
18+
execute_effect,
1819
managed_effect,
1920
managed_pre_effect,
2021
mark_subtree_inert,
@@ -418,7 +419,8 @@ export function bind_transition(dom, transition_fn, props_fn, direction, global)
418419
const block = current_block;
419420
const props = props_fn === null ? {} : props_fn();
420421

421-
let skip_intro = true;
422+
let can_show_intro_on_mount = true;
423+
let can_apply_lazy_transitions = false;
422424

423425
/** @type {import('./types.js').Block | null} */
424426
let transition_block = block;
@@ -429,19 +431,22 @@ export function bind_transition(dom, transition_fn, props_fn, direction, global)
429431
transition_block.r = each_item_transition;
430432
transition_block = transition_block.p;
431433
} else if (transition_block.t === AWAIT_BLOCK && transition_block.n /* pending */) {
432-
skip_intro = false;
434+
can_show_intro_on_mount = false;
435+
} else if (transition_block.t === IF_BLOCK) {
436+
transition_block.r = if_block_transition;
433437
}
434-
if (skip_intro) {
435-
skip_intro = transition_block.e === null;
438+
if (!can_apply_lazy_transitions && can_show_intro_on_mount) {
439+
can_show_intro_on_mount = transition_block.e === null;
436440
}
437-
if (!skip_intro || !global) {
438-
break;
441+
if (!can_show_intro_on_mount || !global) {
442+
can_apply_lazy_transitions = true;
439443
}
440444
} else if (
445+
!can_apply_lazy_transitions &&
441446
transition_block.t === ROOT_BLOCK &&
442447
(transition_block.e !== null || transition_block.i)
443448
) {
444-
skip_intro = false;
449+
can_show_intro_on_mount = false;
445450
}
446451
transition_block = transition_block.p;
447452
}
@@ -467,7 +472,7 @@ export function bind_transition(dom, transition_fn, props_fn, direction, global)
467472

468473
transition = create_transition(dom, init, direction, transition_effect);
469474
const is_intro = direction === 'in';
470-
const show_intro = !skip_intro && (is_intro || direction === 'both');
475+
const show_intro = !can_show_intro_on_mount && (is_intro || direction === 'both');
471476

472477
if (show_intro) {
473478
transition.p = transition.i();
@@ -483,15 +488,15 @@ export function bind_transition(dom, transition_fn, props_fn, direction, global)
483488

484489
/** @type {import('./types.js').Block | null} */
485490
let transition_block = block;
486-
while (transition_block !== null) {
491+
while (!is_intro && transition_block !== null) {
487492
const parent = transition_block.p;
488493
if (is_transition_block(transition_block)) {
489494
if (transition_block.r !== null) {
490495
transition_block.r(transition);
491496
}
492497
if (
493498
parent === null ||
494-
(!global && (transition_block.t !== IF_BLOCK || parent.t !== IF_BLOCK || parent.c))
499+
(!global && (transition_block.t !== IF_BLOCK || parent.t !== IF_BLOCK || parent.v))
495500
) {
496501
break;
497502
}
@@ -510,18 +515,6 @@ export function bind_transition(dom, transition_fn, props_fn, direction, global)
510515
}
511516
}
512517

513-
/**
514-
* @param {Set<import('./types.js').Transition>} transitions
515-
*/
516-
export function remove_in_transitions(transitions) {
517-
for (let transition of transitions) {
518-
const direction = transition.r;
519-
if (direction === 'in') {
520-
transitions.delete(transition);
521-
}
522-
}
523-
}
524-
525518
/**
526519
* @param {Set<import('./types.js').Transition>} transitions
527520
* @param {'in' | 'out' | 'key'} target_direction
@@ -567,6 +560,43 @@ export function trigger_transitions(transitions, target_direction, from) {
567560
}
568561
}
569562

563+
/**
564+
* @this {import('./types.js').IfBlock}
565+
* @param {import('./types.js').Transition} transition
566+
* @returns {void}
567+
*/
568+
function if_block_transition(transition) {
569+
const block = this;
570+
// block.value === true
571+
if (block.v) {
572+
let consequent_transitions = block.c;
573+
if (consequent_transitions === null) {
574+
consequent_transitions = block.c = new Set();
575+
}
576+
consequent_transitions.add(transition);
577+
transition.f(() => {
578+
const c = /** @type {Set<import('./types.js').Transition>} */ (consequent_transitions);
579+
c.delete(transition);
580+
if (c.size === 0) {
581+
execute_effect(/** @type {import('./types.js').EffectSignal} */ (block.ce));
582+
}
583+
});
584+
} else {
585+
let alternate_transitions = block.a;
586+
if (alternate_transitions === null) {
587+
alternate_transitions = block.a = new Set();
588+
}
589+
alternate_transitions.add(transition);
590+
transition.f(() => {
591+
const a = /** @type {Set<import('./types.js').Transition>} */ (alternate_transitions);
592+
a.delete(transition);
593+
if (a.size === 0) {
594+
execute_effect(/** @type {import('./types.js').EffectSignal} */ (block.ae));
595+
}
596+
});
597+
}
598+
}
599+
570600
/**
571601
* @this {import('./types.js').EachItemBlock}
572602
* @param {import('./types.js').Transition} transition

packages/svelte/src/internal/client/types.d.ts

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -165,16 +165,24 @@ export type RootBlock = {
165165
};
166166

167167
export type IfBlock = {
168-
/** current */
169-
c: boolean;
168+
/** value */
169+
v: boolean;
170170
/** dom */
171171
d: null | TemplateNode | Array<TemplateNode>;
172172
/** effect */
173-
e: null | ComputationSignal;
173+
e: null | EffectSignal;
174174
/** parent */
175175
p: Block;
176176
/** transition */
177177
r: null | ((transition: Transition) => void);
178+
/** consequent transitions */
179+
c: null | Set<Transition>;
180+
/** alternate transitions */
181+
a: null | Set<Transition>;
182+
/** effect */
183+
ce: null | EffectSignal;
184+
/** effect */
185+
ae: null | EffectSignal;
178186
/** type */
179187
t: typeof IF_BLOCK;
180188
};
@@ -183,7 +191,7 @@ export type KeyBlock = {
183191
/** dom */
184192
d: null | TemplateNode | Array<TemplateNode>;
185193
/** effect */
186-
e: null | ComputationSignal;
194+
e: null | EffectSignal;
187195
/** parent */
188196
p: Block;
189197
/** transition */

0 commit comments

Comments
 (0)