perf: reuse the cached value in the `<option>`/`<select>` value guard (#18713)

One fewer evaluation of the value expression per update.

---------

Co-authored-by: Simon H <5968653+dummdidumm@users.noreply.github.com>
pull/18717/head
Mathias Picker 1 month ago committed by GitHub
parent 8299cbf11b
commit 6b99f9fb52
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -0,0 +1,5 @@
---
'svelte': patch
---
perf: reuse the cached value in the `<option>`/`<select>` value guard

@ -701,28 +701,32 @@ function build_element_special_value_attribute(
); );
const evaluated = context.state.scope.evaluate(value); const evaluated = context.state.scope.evaluate(value);
const assignment = b.assignment('=', b.member(node_id, '__value'), value);
const set_value_assignment = b.assignment( /** @param {Expression} value */
'=', const build_update = (value) => {
b.member(node_id, 'value'), const assignment = b.assignment('=', b.member(node_id, '__value'), value);
evaluated.is_defined ? assignment : b.logical('??', assignment, b.literal(''))
);
const update = b.stmt( const set_value_assignment = b.assignment(
is_select_with_value '=',
? b.sequence([ b.member(node_id, 'value'),
set_value_assignment, evaluated.is_defined ? assignment : b.logical('??', assignment, b.literal(''))
// This ensures a one-way street to the DOM in case it's <select {value}> );
// and not <select bind:value>. We need it in addition to $.init_select
// because the select value is not reflected as an attribute, so the return b.stmt(
// mutation observer wouldn't notice. is_select_with_value
b.call('$.select_option', node_id, value) ? b.sequence([
]) set_value_assignment,
: synthetic // This ensures a one-way street to the DOM in case it's <select {value}>
? assignment // and not <select bind:value>. We need it in addition to $.init_select
: set_value_assignment // because the select value is not reflected as an attribute, so the
); // mutation observer wouldn't notice.
b.call('$.select_option', node_id, value)
])
: synthetic
? assignment
: set_value_assignment
);
};
if (has_state) { if (has_state) {
const id = b.id(state.scope.generate(`${node_id.name}_value`)); const id = b.id(state.scope.generate(`${node_id.name}_value`));
@ -733,9 +737,14 @@ function build_element_special_value_attribute(
const init = element === 'option' ? b.object([]) : undefined; const init = element === 'option' ? b.object([]) : undefined;
state.init.push(b.var(id, init)); state.init.push(b.var(id, init));
state.update.push(b.if(b.binary('!==', id, b.assignment('=', id, value)), b.block([update])));
// the guard already evaluated `value` into `id`, so read that back rather than
// evaluating the same expression (and its signal reads) a second time
state.update.push(
b.if(b.binary('!==', id, b.assignment('=', id, value)), b.block([build_update(id)]))
);
} else { } else {
state.init.push(update); state.init.push(build_update(value));
} }
if (is_select_with_value) { if (is_select_with_value) {

@ -74,7 +74,7 @@ export default function Select_with_rich_content($$anchor) {
$.set_text(text, $.get(item)); $.set_text(text, $.get(item));
if (option_5_value !== (option_5_value = $.get(item))) { if (option_5_value !== (option_5_value = $.get(item))) {
option_5.__value = $.get(item); option_5.__value = option_5_value;
} }
}); });
@ -137,7 +137,7 @@ export default function Select_with_rich_content($$anchor) {
$.set_text(text_1, $.get(x)); $.set_text(text_1, $.get(x));
if (option_8_value !== (option_8_value = $.get(x))) { if (option_8_value !== (option_8_value = $.get(x))) {
option_8.__value = $.get(x); option_8.__value = option_8_value;
} }
}); });
@ -175,7 +175,7 @@ export default function Select_with_rich_content($$anchor) {
$.set_text(text_2, $.get(item)); $.set_text(text_2, $.get(item));
if (option_10_value !== (option_10_value = $.get(item))) { if (option_10_value !== (option_10_value = $.get(item))) {
option_10.__value = $.get(item); option_10.__value = option_10_value;
} }
}); });
@ -240,7 +240,7 @@ export default function Select_with_rich_content($$anchor) {
$.set_text(text_4, $.get(item)); $.set_text(text_4, $.get(item));
if (option_13_value !== (option_13_value = $.get(item))) { if (option_13_value !== (option_13_value = $.get(item))) {
option_13.__value = $.get(item); option_13.__value = option_13_value;
} }
}); });

Loading…
Cancel
Save