Skip to content

Commit

Permalink
Merge pull request #2865 from sveltejs/less-invalidation
Browse files Browse the repository at this point in the history
only invalidate referenced values
  • Loading branch information
Rich-Harris authored May 27, 2019
2 parents 60a2a51 + e8b769c commit ed72aea
Show file tree
Hide file tree
Showing 11 changed files with 152 additions and 27 deletions.
9 changes: 7 additions & 2 deletions src/compile/Component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -789,6 +789,10 @@ export default class Component {
return `${name.slice(1)}.set(${name})`
}

if (variable && !variable.referenced && !variable.is_reactive_dependency && !variable.export_name && !name.startsWith('$$')) {
return value || name;
}

if (value) {
return `$$invalidate('${name}', ${value})`;
}
Expand Down Expand Up @@ -1120,8 +1124,9 @@ export default class Component {
if (!assignee_nodes.has(identifier)) {
const { name } = identifier;
const owner = scope.find_owner(name);
const component_var = component.var_lookup.get(name);
const is_writable_or_mutated = component_var && (component_var.writable || component_var.mutated);
const variable = component.var_lookup.get(name);
if (variable) variable.is_reactive_dependency = true;
const is_writable_or_mutated = variable && (variable.writable || variable.mutated);
if (
(!owner || owner === component.instance_scope) &&
(name[0] === '$' || is_writable_or_mutated)
Expand Down
6 changes: 4 additions & 2 deletions src/compile/render-dom/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -203,8 +203,10 @@ export default function dom(
if (variable && (variable.hoistable || variable.global || variable.module)) return;

if (single && !(variable.subscribable && variable.reassigned)) {
code.prependRight(node.start, `$$invalidate('${name}', `);
code.appendLeft(node.end, `)`);
if (variable.referenced || variable.is_reactive_dependency || variable.export_name) {
code.prependRight(node.start, `$$invalidate('${name}', `);
code.appendLeft(node.end, `)`);
}
} else {
pending_assignments.add(name);
}
Expand Down
3 changes: 2 additions & 1 deletion src/interfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -133,4 +133,5 @@ export interface Var {
initialised?: boolean;
hoistable?: boolean;
subscribable?: boolean;
}
is_reactive_dependency?: boolean;
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ function instance($$self, $$props, $$invalidate) {

$$self.$$.update = ($$dirty = { x: 1, b: 1 }) => {
if ($$dirty.x) { $$invalidate('b', b = x); }
if ($$dirty.b) { $$invalidate('a', a = b); }
if ($$dirty.b) { a = b; }
};

return { x };
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,26 +17,25 @@ function create_fragment(ctx) {
};
}

let a = 1;

let b = 2;

function instance($$self, $$props, $$invalidate) {

let { a = 1, b = 2 } = $$props;

let max;
$$self.$set = $$props => {
if ('a' in $$props) $$invalidate('a', a = $$props.a);
if ('b' in $$props) $$invalidate('b', b = $$props.b);
};

$$self.$$.update = ($$dirty = { a: 1, b: 1 }) => {
if ($$dirty.a || $$dirty.b) { $$invalidate('max', max = Math.max(a, b)); }
if ($$dirty.a || $$dirty.b) { console.log('max', Math.max(a, b)); }
};

return {};
return { a, b };
}

class Component extends SvelteComponent {
constructor(options) {
super();
init(this, options, instance, create_fragment, safe_not_equal, []);
init(this, options, instance, create_fragment, safe_not_equal, ["a", "b"]);
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
<script>
let a = 1;
let b = 2;
export let a = 1;
export let b = 2;

let max;
$: max = Math.max(a, b);
$: console.log('max', Math.max(a, b));
</script>
78 changes: 78 additions & 0 deletions test/js/samples/unreferenced-state-not-invalidated/expected.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
/* generated by Svelte vX.Y.Z */
import {
SvelteComponent,
append,
detach,
element,
init,
insert,
noop,
safe_not_equal,
set_data,
text
} from "svelte/internal";
import { onMount } from "svelte";

function create_fragment(ctx) {
var p, t;

return {
c() {
p = element("p");
t = text(ctx.y);
},

m(target, anchor) {
insert(target, p, anchor);
append(p, t);
},

p(changed, ctx) {
if (changed.y) {
set_data(t, ctx.y);
}
},

i: noop,
o: noop,

d(detaching) {
if (detaching) {
detach(p);
}
}
};
}

function instance($$self, $$props, $$invalidate) {
let a, b, c;

onMount(() => {
const interval = setInterval(() => {
$$invalidate('b', b += 1);
c += 1;

console.log(b, c);
}, 1000);

return () => clearInterval(interval);
});

let x, y;

$$self.$$.update = ($$dirty = { a: 1, b: 1 }) => {
if ($$dirty.a) { x = a * 2; }
if ($$dirty.b) { $$invalidate('y', y = b * 2); }
};

return { y };
}

class Component extends SvelteComponent {
constructor(options) {
super();
init(this, options, instance, create_fragment, safe_not_equal, []);
}
}

export default Component;
21 changes: 21 additions & 0 deletions test/js/samples/unreferenced-state-not-invalidated/input.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<script>
import { onMount } from 'svelte';

let a, b, c;

onMount(() => {
const interval = setInterval(() => {
b += 1;
c += 1;

console.log(b, c);
}, 1000);

return () => clearInterval(interval);
});

$: x = a * 2;
$: y = b * 2;
</script>

<p>{y}</p>
5 changes: 3 additions & 2 deletions test/runtime/samples/immutable-nested/Nested.svelte
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<script>
import { beforeUpdate, onMount } from 'svelte';

let mounted;
let mounted = false;
export let count = 0;
export let foo = { bar: 'baz' };

Expand All @@ -14,4 +14,5 @@
});
</script>

<h3>Called {count} times.</h3>
<h3>Called {count} times.</h3>
<p>{foo.bar} {mounted}</p>
29 changes: 24 additions & 5 deletions test/runtime/samples/immutable-nested/_config.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,35 @@
export default {
immutable: true,

html: `<div><h3>Called 1 times.</h3></div>`,
html: `
<div>
<h3>Called 1 times.</h3>
<p>baz true</p>
</div>
`,

ssrHtml: `<div><h3>Called 0 times.</h3></div>`,
ssrHtml: `
<div>
<h3>Called 0 times.</h3>
<p>baz false</p>
</div>`,

test({ assert, component, target, window }) {
test({ assert, component, target }) {
var nested = component.nested;

assert.htmlEqual(target.innerHTML, `<div><h3>Called 1 times.</h3></div>`);
assert.htmlEqual(target.innerHTML, `
<div>
<h3>Called 1 times.</h3>
<p>baz true</p>
</div>
`);

nested.foo = nested.foo;
assert.htmlEqual(target.innerHTML, `<div><h3>Called 1 times.</h3></div>`);
assert.htmlEqual(target.innerHTML, `
<div>
<h3>Called 1 times.</h3>
<p>baz true</p>
</div>
`);
}
};
2 changes: 1 addition & 1 deletion test/runtime/samples/immutable-nested/main.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,5 @@
</script>

<div>
<Nested bind:this={nested} />
<Nested bind:this={nested} />
</div>

0 comments on commit ed72aea

Please sign in to comment.