Skip to content

Commit aaceaf9

Browse files
committed
feat no invalidate reactive vars if dependencies are all static
1 parent 6a4956b commit aaceaf9

File tree

5 files changed

+85
-5
lines changed

5 files changed

+85
-5
lines changed

src/compiler/compile/Component.ts

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import { Node, ImportDeclaration, Identifier, Program, ExpressionStatement, Assi
2828
import add_to_set from './utils/add_to_set';
2929
import check_graph_for_cycles from './utils/check_graph_for_cycles';
3030
import { print, x, b } from 'code-red';
31+
import is_dynamic from './render_dom/wrappers/shared/is_dynamic';
3132

3233
interface ComponentOptions {
3334
namespace?: string;
@@ -1144,9 +1145,9 @@ export default class Component {
11441145
if (node.type === 'LabeledStatement' && node.label.name === '$') {
11451146
this.reactive_declaration_nodes.add(node);
11461147

1147-
const assignees = new Set();
1148+
const assignees = new Set<string>();
11481149
const assignee_nodes = new Set();
1149-
const dependencies = new Set();
1150+
const dependencies = new Set<string>();
11501151

11511152
let scope = this.instance_scope;
11521153
const map = this.instance_scope_map;
@@ -1178,11 +1179,10 @@ export default class Component {
11781179
const owner = scope.find_owner(name);
11791180
const variable = component.var_lookup.get(name);
11801181
if (variable) variable.is_reactive_dependency = true;
1181-
const is_writable_or_mutated =
1182-
variable && (variable.writable || variable.mutated);
1182+
11831183
if (
11841184
(!owner || owner === component.instance_scope) &&
1185-
(name[0] === '$' || is_writable_or_mutated)
1185+
(name[0] === '$' || variable)
11861186
) {
11871187
dependencies.add(name);
11881188
}
@@ -1202,6 +1202,17 @@ export default class Component {
12021202
const { expression } = node.body as ExpressionStatement;
12031203
const declaration = expression && (expression as AssignmentExpression).left;
12041204

1205+
const is_dependency_static = Array.from(dependencies).every(dependency => dependency !== '$$props' && !is_dynamic(this.var_lookup.get(dependency)));
1206+
1207+
if (is_dependency_static) {
1208+
assignees.forEach(assignee => {
1209+
const variable = component.var_lookup.get(assignee);
1210+
if (variable) {
1211+
variable.is_reactive_static = true;
1212+
}
1213+
});
1214+
}
1215+
12051216
unsorted_reactive_declarations.push({
12061217
assignees,
12071218
dependencies,

src/compiler/compile/render_dom/invalidate.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ export function invalidate(renderer: Renderer, scope: Scope, node: Node, names:
1717
!variable.hoistable &&
1818
!variable.global &&
1919
!variable.module &&
20+
!variable.is_reactive_static &&
2021
(
2122
variable.referenced ||
2223
variable.subscribable ||

src/compiler/interfaces.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,4 +160,5 @@ export interface Var {
160160
hoistable?: boolean;
161161
subscribable?: boolean;
162162
is_reactive_dependency?: boolean;
163+
is_reactive_static?: boolean;
163164
}
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
/* generated by Svelte vX.Y.Z */
2+
import {
3+
SvelteComponent,
4+
detach,
5+
element,
6+
init,
7+
insert,
8+
noop,
9+
safe_not_equal,
10+
set_data,
11+
space,
12+
text
13+
} from "svelte/internal";
14+
15+
function create_fragment(ctx) {
16+
let h1;
17+
let t3;
18+
let t4;
19+
20+
return {
21+
c() {
22+
h1 = element("h1");
23+
h1.textContent = `Hello ${name}!`;
24+
t3 = space();
25+
t4 = text(/*foo*/ ctx[0]);
26+
},
27+
m(target, anchor) {
28+
insert(target, h1, anchor);
29+
insert(target, t3, anchor);
30+
insert(target, t4, anchor);
31+
},
32+
p(ctx, [dirty]) {
33+
if (dirty & /*foo*/ 1) set_data(t4, /*foo*/ ctx[0]);
34+
},
35+
i: noop,
36+
o: noop,
37+
d(detaching) {
38+
if (detaching) detach(h1);
39+
if (detaching) detach(t3);
40+
if (detaching) detach(t4);
41+
}
42+
};
43+
}
44+
45+
let name = "world";
46+
47+
function instance($$self) {
48+
let foo;
49+
$: foo = name + name;
50+
return [foo];
51+
}
52+
53+
class Component extends SvelteComponent {
54+
constructor(options) {
55+
super();
56+
init(this, options, instance, create_fragment, safe_not_equal, {});
57+
}
58+
}
59+
60+
export default Component;
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<script>
2+
let name = 'world';
3+
$: foo = name + name;
4+
</script>
5+
6+
<h1>Hello {name}!</h1>
7+
{foo}

0 commit comments

Comments
 (0)