From fbaf3cfc1249645e7f0cc49fa3caab0a4ed6433e Mon Sep 17 00:00:00 2001 From: Tan Li Hau Date: Thu, 2 Mar 2023 00:28:37 +0800 Subject: [PATCH] fix: call `` update to `this` only when it's dirty (#4192) Closes #4129 --------- Co-authored-by: Simon H <5968653+dummdidumm@users.noreply.github.com> Co-authored-by: Simon Holthausen --- .../wrappers/InlineComponent/index.ts | 8 ++++++- .../dynamic-component-dirty/_config.js | 24 +++++++++++++++++++ .../dynamic-component-dirty/main.svelte | 16 +++++++++++++ 3 files changed, 47 insertions(+), 1 deletion(-) create mode 100644 test/runtime/samples/dynamic-component-dirty/_config.js create mode 100644 test/runtime/samples/dynamic-component-dirty/main.svelte diff --git a/src/compiler/compile/render_dom/wrappers/InlineComponent/index.ts b/src/compiler/compile/render_dom/wrappers/InlineComponent/index.ts index 5053e8c5d2..ab140a75c5 100644 --- a/src/compiler/compile/render_dom/wrappers/InlineComponent/index.ts +++ b/src/compiler/compile/render_dom/wrappers/InlineComponent/index.ts @@ -418,6 +418,7 @@ export default class InlineComponentWrapper extends Wrapper { const switch_props = block.get_unique_name('switch_props'); const snippet = this.node.expression.manipulate(block); + const dependencies = this.node.expression.dynamic_dependencies(); if (has_css_custom_properties) { this.set_css_custom_properties(block, css_custom_properties_wrapper, css_custom_properties_wrapper_element, is_svg_namespace); @@ -468,8 +469,13 @@ export default class InlineComponentWrapper extends Wrapper { ? b`@insert(${tmp_anchor}.parentNode, ${css_custom_properties_wrapper}, ${tmp_anchor});` : b`@insert(${parent_node}, ${css_custom_properties_wrapper}, ${tmp_anchor});`); + let update_condition = x`${switch_value} !== (${switch_value} = ${snippet})`; + if (dependencies.length > 0) { + update_condition = x`${block.renderer.dirty(dependencies)} && ${update_condition}`; + } + block.chunks.update.push(b` - if (${switch_value} !== (${switch_value} = ${snippet})) { + if (${update_condition}) { if (${name}) { @group_outros(); const old_component = ${name}; diff --git a/test/runtime/samples/dynamic-component-dirty/_config.js b/test/runtime/samples/dynamic-component-dirty/_config.js new file mode 100644 index 0000000000..bace92f21b --- /dev/null +++ b/test/runtime/samples/dynamic-component-dirty/_config.js @@ -0,0 +1,24 @@ +const calls = []; +export default { + props: { + calls + }, + + before_test() { + calls.length = 0; + }, + + async test({ assert, component, target, window }) { + const buttons = target.querySelector('button'); + + assert.deepEqual(calls.length, 1); + + const event = new window.MouseEvent('click'); + await buttons.dispatchEvent(event); + + assert.deepEqual(calls.length, 1); + + component.current_path = 'bar'; + assert.deepEqual(calls.length, 2); + } +}; diff --git a/test/runtime/samples/dynamic-component-dirty/main.svelte b/test/runtime/samples/dynamic-component-dirty/main.svelte new file mode 100644 index 0000000000..37317e98aa --- /dev/null +++ b/test/runtime/samples/dynamic-component-dirty/main.svelte @@ -0,0 +1,16 @@ + + + + +{i}