Skip to content

Commit 335a49e

Browse files
committed
breaking: removed deferred event updates
1 parent aa91ed2 commit 335a49e

File tree

19 files changed

+147
-102
lines changed

19 files changed

+147
-102
lines changed

.changeset/sixty-plants-cover.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+
breaking: removed deferred event updates

packages/svelte/src/internal/client/dom/elements/bindings/input.js

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import { stringify } from '../../../render.js';
44
import { listen_to_event_and_reset_event } from './shared.js';
55
import * as e from '../../../errors.js';
66
import { get_proxied_value, is } from '../../../proxy.js';
7-
import { yield_event_updates } from '../../../runtime.js';
87

98
/**
109
* @param {HTMLInputElement} input
@@ -19,9 +18,7 @@ export function bind_value(input, get_value, update) {
1918
e.bind_invalid_checkbox_value();
2019
}
2120

22-
yield_event_updates(() =>
23-
update(is_numberlike_input(input) ? to_number(input.value) : input.value)
24-
);
21+
update(is_numberlike_input(input) ? to_number(input.value) : input.value);
2522
});
2623

2724
render_effect(() => {
@@ -87,10 +84,10 @@ export function bind_group(inputs, group_index, input, get_value, update) {
8784
value = get_binding_group_value(binding_group, value, input.checked);
8885
}
8986

90-
yield_event_updates(() => update(value));
87+
update(value);
9188
},
9289
// TODO better default value handling
93-
() => yield_event_updates(() => update(is_checkbox ? [] : null))
90+
() => update(is_checkbox ? [] : null)
9491
);
9592

9693
render_effect(() => {
@@ -131,7 +128,7 @@ export function bind_group(inputs, group_index, input, get_value, update) {
131128
export function bind_checked(input, get_value, update) {
132129
listen_to_event_and_reset_event(input, 'change', () => {
133130
var value = input.checked;
134-
yield_event_updates(() => update(value));
131+
update(value);
135132
});
136133

137134
if (get_value() == undefined) {
@@ -190,7 +187,7 @@ function to_number(value) {
190187
*/
191188
export function bind_files(input, get_value, update) {
192189
listen_to_event_and_reset_event(input, 'change', () => {
193-
yield_event_updates(() => update(input.files));
190+
update(input.files);
194191
});
195192
render_effect(() => {
196193
input.files = get_value();

packages/svelte/src/internal/client/dom/elements/bindings/media.js

Lines changed: 10 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import { hydrating } from '../../hydration.js';
22
import { render_effect, effect } from '../../../reactivity/effects.js';
33
import { listen } from './shared.js';
4-
import { yield_event_updates } from '../../../runtime.js';
54

65
/** @param {TimeRanges} ranges */
76
function time_ranges_to_array(ranges) {
@@ -36,7 +35,7 @@ export function bind_current_time(media, get_value, update) {
3635
}
3736

3837
updating = true;
39-
yield_event_updates(() => update(media.currentTime));
38+
update(media.currentTime);
4039
};
4140

4241
raf_id = requestAnimationFrame(callback);
@@ -61,9 +60,7 @@ export function bind_current_time(media, get_value, update) {
6160
* @param {(array: Array<{ start: number; end: number }>) => void} update
6261
*/
6362
export function bind_buffered(media, update) {
64-
listen(media, ['loadedmetadata', 'progress'], () =>
65-
yield_event_updates(() => update(time_ranges_to_array(media.buffered)))
66-
);
63+
listen(media, ['loadedmetadata', 'progress'], () => update(time_ranges_to_array(media.buffered)));
6764
}
6865

6966
/**
@@ -79,25 +76,23 @@ export function bind_seekable(media, update) {
7976
* @param {(array: Array<{ start: number; end: number }>) => void} update
8077
*/
8178
export function bind_played(media, update) {
82-
listen(media, ['timeupdate'], () =>
83-
yield_event_updates(() => update(time_ranges_to_array(media.played)))
84-
);
79+
listen(media, ['timeupdate'], () => update(time_ranges_to_array(media.played)));
8580
}
8681

8782
/**
8883
* @param {HTMLVideoElement | HTMLAudioElement} media
8984
* @param {(seeking: boolean) => void} update
9085
*/
9186
export function bind_seeking(media, update) {
92-
listen(media, ['seeking', 'seeked'], () => yield_event_updates(() => update(media.seeking)));
87+
listen(media, ['seeking', 'seeked'], () => update(media.seeking));
9388
}
9489

9590
/**
9691
* @param {HTMLVideoElement | HTMLAudioElement} media
9792
* @param {(seeking: boolean) => void} update
9893
*/
9994
export function bind_ended(media, update) {
100-
listen(media, ['timeupdate', 'ended'], () => yield_event_updates(() => update(media.ended)));
95+
listen(media, ['timeupdate', 'ended'], () => update(media.ended));
10196
}
10297

10398
/**
@@ -108,7 +103,7 @@ export function bind_ready_state(media, update) {
108103
listen(
109104
media,
110105
['loadedmetadata', 'loadeddata', 'canplay', 'canplaythrough', 'playing', 'waiting', 'emptied'],
111-
() => yield_event_updates(() => update(media.readyState))
106+
() => update(media.readyState)
112107
);
113108
}
114109

@@ -132,7 +127,7 @@ export function bind_playback_rate(media, get_value, update) {
132127
}
133128

134129
listen(media, ['ratechange'], () => {
135-
if (!updating) yield_event_updates(() => update(media.playbackRate));
130+
if (!updating) update(media.playbackRate);
136131
updating = false;
137132
});
138133
});
@@ -150,7 +145,7 @@ export function bind_paused(media, get_value, update) {
150145
var callback = () => {
151146
if (paused !== media.paused) {
152147
paused = media.paused;
153-
yield_event_updates(() => update((paused = media.paused)));
148+
update((paused = media.paused));
154149
}
155150
};
156151

@@ -175,7 +170,7 @@ export function bind_paused(media, get_value, update) {
175170
media.pause();
176171
} else {
177172
media.play().catch(() => {
178-
yield_event_updates(() => update((paused = true)));
173+
update((paused = true));
179174
});
180175
}
181176
};
@@ -239,7 +234,7 @@ export function bind_muted(media, get_value, update) {
239234

240235
var callback = () => {
241236
updating = true;
242-
yield_event_updates(() => update(media.muted));
237+
update(media.muted);
243238
};
244239

245240
if (get_value() == null) {
Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import { yield_event_updates } from '../../../runtime.js';
21
import { listen } from './shared.js';
32

43
/**
@@ -7,6 +6,6 @@ import { listen } from './shared.js';
76
*/
87
export function bind_online(update) {
98
listen(window, ['online', 'offline'], () => {
10-
yield_event_updates(() => update(navigator.onLine));
9+
update(navigator.onLine);
1110
});
1211
}

packages/svelte/src/internal/client/dom/elements/bindings/select.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { effect } from '../../../reactivity/effects.js';
22
import { listen_to_event_and_reset_event } from './shared.js';
3-
import { untrack, yield_event_updates } from '../../../runtime.js';
3+
import { untrack } from '../../../runtime.js';
44
import { is } from '../../../proxy.js';
55

66
/**
@@ -90,7 +90,7 @@ export function bind_select_value(select, get_value, update) {
9090
value = selected_option && get_option_value(selected_option);
9191
}
9292

93-
yield_event_updates(() => update(value));
93+
update(value);
9494
});
9595

9696
// Needs to be an effect, not a render_effect, so that in case of each loops the logic runs after the each block has updated

packages/svelte/src/internal/client/dom/elements/bindings/size.js

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { effect, render_effect } from '../../../reactivity/effects.js';
2-
import { untrack, yield_event_updates } from '../../../runtime.js';
2+
import { untrack } from '../../../runtime.js';
33

44
/**
55
* Resize observer singleton.
@@ -88,10 +88,7 @@ export function bind_resize_observer(element, type, update) {
8888
? resize_observer_border_box
8989
: resize_observer_device_pixel_content_box;
9090

91-
var unsub = observer.observe(
92-
element,
93-
/** @param {any} entry */ (entry) => yield_event_updates(() => update(entry[type]))
94-
);
91+
var unsub = observer.observe(element, /** @param {any} entry */ (entry) => update(entry[type]));
9592
render_effect(() => unsub);
9693
}
9794

@@ -104,7 +101,7 @@ export function bind_element_size(element, type, update) {
104101
var unsub = resize_observer_border_box.observe(element, () => update(element[type]));
105102

106103
effect(() => {
107-
yield_event_updates(() => untrack(() => update(element[type])));
104+
update(element[type]);
108105
return unsub;
109106
});
110107
}

packages/svelte/src/internal/client/dom/elements/bindings/this.js

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { STATE_SYMBOL } from '../../../constants.js';
22
import { effect, render_effect } from '../../../reactivity/effects.js';
3-
import { untrack, yield_event_updates } from '../../../runtime.js';
3+
import { untrack } from '../../../runtime.js';
44
import { queue_micro_task } from '../../task.js';
55

66
/**
@@ -37,14 +37,12 @@ export function bind_this(element_or_component, update, get_value, get_parts) {
3737

3838
untrack(() => {
3939
if (element_or_component !== get_value(...parts)) {
40-
yield_event_updates(() => {
41-
update(element_or_component, ...parts);
42-
// If this is an effect rerun (cause: each block context changes), then nullfiy the binding at
43-
// the previous position if it isn't already taken over by a different effect.
44-
if (old_parts && is_bound_this(get_value(...old_parts), element_or_component)) {
45-
update(null, ...old_parts);
46-
}
47-
});
40+
update(element_or_component, ...parts);
41+
// If this is an effect rerun (cause: each block context changes), then nullfiy the binding at
42+
// the previous position if it isn't already taken over by a different effect.
43+
if (old_parts && is_bound_this(get_value(...old_parts), element_or_component)) {
44+
update(null, ...old_parts);
45+
}
4846
}
4947
});
5048
});

packages/svelte/src/internal/client/dom/elements/bindings/window.js

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import { effect, render_effect } from '../../../reactivity/effects.js';
2-
import { yield_event_updates } from '../../../runtime.js';
32
import { listen } from './shared.js';
43

54
/**
@@ -16,7 +15,7 @@ export function bind_window_scroll(type, get_value, update) {
1615
clearTimeout(timeout);
1716
timeout = setTimeout(clear, 100); // TODO use scrollend event if supported (or when supported everywhere?)
1817

19-
yield_event_updates(() => update(window[is_scrolling_x ? 'scrollX' : 'scrollY']));
18+
update(window[is_scrolling_x ? 'scrollX' : 'scrollY']);
2019
};
2120

2221
addEventListener('scroll', target_handler, {
@@ -64,5 +63,5 @@ export function bind_window_scroll(type, get_value, update) {
6463
* @param {(size: number) => void} update
6564
*/
6665
export function bind_window_size(type, update) {
67-
listen(window, ['resize'], () => yield_event_updates(() => update(window[type])));
66+
listen(window, ['resize'], () => update(window[type]));
6867
}

packages/svelte/src/internal/client/dom/elements/events.js

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import { render_effect } from '../../reactivity/effects.js';
22
import { all_registered_events, root_event_handles } from '../../render.js';
3-
import { yield_event_updates } from '../../runtime.js';
43
import { define_property, is_array } from '../../utils.js';
54
import { hydrating } from '../hydration.js';
65
import { queue_micro_task } from '../task.js';
@@ -48,7 +47,7 @@ export function create_event(event_name, dom, handler, options) {
4847
handle_event_propagation(dom, event);
4948
}
5049
if (!event.cancelBubble) {
51-
return yield_event_updates(() => handler.call(this, event));
50+
return handler.call(this, event);
5251
}
5352
}
5453

@@ -204,7 +203,7 @@ export function handle_event_propagation(handler_element, event) {
204203
}
205204

206205
try {
207-
yield_event_updates(() => next(/** @type {Element} */ (current_target)));
206+
next(/** @type {Element} */ (current_target));
208207
} finally {
209208
// @ts-expect-error is used above
210209
event.__root = handler_element;

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

Lines changed: 2 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@ import { lifecycle_outside_component } from '../shared/errors.js';
2929

3030
const FLUSH_MICROTASK = 0;
3131
const FLUSH_SYNC = 1;
32-
export const FLUSH_YIELD = 2;
3332

3433
// Used for DEV time error handling
3534
/** @param {WeakSet<Error>} value */
@@ -38,7 +37,6 @@ const handled_errors = new WeakSet();
3837
let current_scheduler_mode = FLUSH_MICROTASK;
3938
// Used for handling scheduling
4039
let is_micro_task_queued = false;
41-
let is_yield_task_queued = false;
4240

4341
export let is_flushing_effect = false;
4442
export let is_destroying_effect = false;
@@ -599,29 +597,17 @@ function flush_queued_effects(effects) {
599597

600598
function process_deferred() {
601599
is_micro_task_queued = false;
602-
is_yield_task_queued = false;
603600
if (flush_count > 1001) {
604601
return;
605602
}
606603
const previous_queued_root_effects = current_queued_root_effects;
607604
current_queued_root_effects = [];
608605
flush_queued_root_effects(previous_queued_root_effects);
609-
if (!is_micro_task_queued && !is_yield_task_queued) {
606+
if (!is_micro_task_queued) {
610607
flush_count = 0;
611608
}
612609
}
613610

614-
async function yield_tick() {
615-
// TODO: replace this with scheduler.yield when it becomes standard
616-
await new Promise((fulfil) => {
617-
requestAnimationFrame(() => {
618-
setTimeout(fulfil, 0);
619-
});
620-
// In case of being within background tab, the rAF won't fire
621-
setTimeout(fulfil, 100);
622-
});
623-
}
624-
625611
/**
626612
* @param {import('#client').Effect} signal
627613
* @returns {void}
@@ -632,11 +618,6 @@ export function schedule_effect(signal) {
632618
is_micro_task_queued = true;
633619
queueMicrotask(process_deferred);
634620
}
635-
} else if (current_scheduler_mode === FLUSH_YIELD) {
636-
if (!is_yield_task_queued) {
637-
is_yield_task_queued = true;
638-
yield_tick().then(process_deferred);
639-
}
640621
}
641622

642623
var effect = signal;
@@ -735,19 +716,6 @@ function process_effects(effect, collected_effects) {
735716
}
736717
}
737718

738-
/**
739-
* @param {{ (): void; (): any; }} fn
740-
*/
741-
export function yield_event_updates(fn) {
742-
const previous_scheduler_mode = current_scheduler_mode;
743-
try {
744-
current_scheduler_mode = FLUSH_YIELD;
745-
return fn();
746-
} finally {
747-
current_scheduler_mode = previous_scheduler_mode;
748-
}
749-
}
750-
751719
/**
752720
* Internal version of `flushSync` with the option to not flush previous effects.
753721
* Returns the result of the passed function, if given.
@@ -767,7 +735,6 @@ export function flush_sync(fn, flush_previous = true) {
767735

768736
current_scheduler_mode = FLUSH_SYNC;
769737
current_queued_root_effects = root_effects;
770-
is_yield_task_queued = false;
771738
is_micro_task_queued = false;
772739

773740
if (flush_previous) {
@@ -795,7 +762,7 @@ export function flush_sync(fn, flush_previous = true) {
795762
* @returns {Promise<void>}
796763
*/
797764
export async function tick() {
798-
await yield_tick();
765+
await Promise.resolve();
799766
// By calling flush_sync we guarantee that any pending state changes are applied after one tick.
800767
// TODO look into whether we can make flushing subsequent updates synchronously in the future.
801768
flush_sync();

0 commit comments

Comments
 (0)