Skip to content

Commit 4f05cc3

Browse files
authored
don't create class update functions when dependencies aren't reactive (#5926)
1 parent 6207596 commit 4f05cc3

File tree

4 files changed

+216
-4
lines changed

4 files changed

+216
-4
lines changed

src/compiler/compile/render_dom/wrappers/Element/index.ts

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import Action from '../../../nodes/Action';
2626
import MustacheTagWrapper from '../MustacheTag';
2727
import RawMustacheTagWrapper from '../RawMustacheTag';
2828
import create_slot_block from './create_slot_block';
29+
import is_dynamic from '../shared/is_dynamic';
2930

3031
interface BindingGroup {
3132
events: string[];
@@ -898,10 +899,19 @@ export default class ElementWrapper extends Wrapper {
898899
const all_dependencies = this.class_dependencies.concat(...dependencies);
899900
const condition = block.renderer.dirty(all_dependencies);
900901

901-
block.chunks.update.push(b`
902-
if (${condition}) {
903-
${updater}
904-
}`);
902+
// If all of the dependencies are non-dynamic (don't get updated) then there is no reason
903+
// to add an updater for this.
904+
const any_dynamic_dependencies = all_dependencies.some((dep) => {
905+
const variable = this.renderer.component.var_lookup.get(dep);
906+
return !variable || is_dynamic(variable);
907+
});
908+
if (any_dynamic_dependencies) {
909+
block.chunks.update.push(b`
910+
if (${condition}) {
911+
${updater}
912+
}
913+
`);
914+
}
905915
}
906916
});
907917
}
Lines changed: 167 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
1+
/* generated by Svelte vX.Y.Z */
2+
import {
3+
SvelteComponent,
4+
component_subscribe,
5+
detach,
6+
element,
7+
init,
8+
insert,
9+
noop,
10+
safe_not_equal,
11+
space,
12+
subscribe,
13+
toggle_class
14+
} from "svelte/internal";
15+
16+
import { reactiveStoreVal, unreactiveExport } from "./store";
17+
18+
function create_fragment(ctx) {
19+
let div0;
20+
let t0;
21+
let div1;
22+
let t1;
23+
let div2;
24+
let t2;
25+
let div3;
26+
let t3;
27+
let div4;
28+
let t4;
29+
let div5;
30+
let t5;
31+
let div6;
32+
let t6;
33+
let div7;
34+
let t7;
35+
let div8;
36+
37+
return {
38+
c() {
39+
div0 = element("div");
40+
t0 = space();
41+
div1 = element("div");
42+
t1 = space();
43+
div2 = element("div");
44+
t2 = space();
45+
div3 = element("div");
46+
t3 = space();
47+
div4 = element("div");
48+
t4 = space();
49+
div5 = element("div");
50+
t5 = space();
51+
div6 = element("div");
52+
t6 = space();
53+
div7 = element("div");
54+
t7 = space();
55+
div8 = element("div");
56+
toggle_class(div0, "update1", reactiveModuleVar);
57+
toggle_class(div1, "update2", /*reactiveConst*/ ctx[0].x);
58+
toggle_class(div2, "update3", nonReactiveGlobal && /*reactiveConst*/ ctx[0].x);
59+
toggle_class(div3, "update4", /*$reactiveStoreVal*/ ctx[2]);
60+
toggle_class(div4, "update5", /*$reactiveDeclaration*/ ctx[3]);
61+
toggle_class(div5, "static1", nonReactiveModuleVar);
62+
toggle_class(div6, "static2", nonReactiveGlobal);
63+
toggle_class(div7, "static3", nonReactiveModuleVar && nonReactiveGlobal);
64+
toggle_class(div8, "static4", unreactiveExport);
65+
},
66+
m(target, anchor) {
67+
insert(target, div0, anchor);
68+
insert(target, t0, anchor);
69+
insert(target, div1, anchor);
70+
insert(target, t1, anchor);
71+
insert(target, div2, anchor);
72+
insert(target, t2, anchor);
73+
insert(target, div3, anchor);
74+
insert(target, t3, anchor);
75+
insert(target, div4, anchor);
76+
insert(target, t4, anchor);
77+
insert(target, div5, anchor);
78+
insert(target, t5, anchor);
79+
insert(target, div6, anchor);
80+
insert(target, t6, anchor);
81+
insert(target, div7, anchor);
82+
insert(target, t7, anchor);
83+
insert(target, div8, anchor);
84+
},
85+
p(ctx, [dirty]) {
86+
if (dirty & /*reactiveModuleVar*/ 0) {
87+
toggle_class(div0, "update1", reactiveModuleVar);
88+
}
89+
90+
if (dirty & /*reactiveConst*/ 1) {
91+
toggle_class(div1, "update2", /*reactiveConst*/ ctx[0].x);
92+
}
93+
94+
if (dirty & /*nonReactiveGlobal, reactiveConst*/ 1) {
95+
toggle_class(div2, "update3", nonReactiveGlobal && /*reactiveConst*/ ctx[0].x);
96+
}
97+
98+
if (dirty & /*$reactiveStoreVal*/ 4) {
99+
toggle_class(div3, "update4", /*$reactiveStoreVal*/ ctx[2]);
100+
}
101+
102+
if (dirty & /*$reactiveDeclaration*/ 8) {
103+
toggle_class(div4, "update5", /*$reactiveDeclaration*/ ctx[3]);
104+
}
105+
},
106+
i: noop,
107+
o: noop,
108+
d(detaching) {
109+
if (detaching) detach(div0);
110+
if (detaching) detach(t0);
111+
if (detaching) detach(div1);
112+
if (detaching) detach(t1);
113+
if (detaching) detach(div2);
114+
if (detaching) detach(t2);
115+
if (detaching) detach(div3);
116+
if (detaching) detach(t3);
117+
if (detaching) detach(div4);
118+
if (detaching) detach(t4);
119+
if (detaching) detach(div5);
120+
if (detaching) detach(t5);
121+
if (detaching) detach(div6);
122+
if (detaching) detach(t6);
123+
if (detaching) detach(div7);
124+
if (detaching) detach(t7);
125+
if (detaching) detach(div8);
126+
}
127+
};
128+
}
129+
130+
let nonReactiveModuleVar = Math.random();
131+
let reactiveModuleVar = Math.random();
132+
133+
function instance($$self, $$props, $$invalidate) {
134+
let reactiveDeclaration;
135+
let $reactiveStoreVal;
136+
137+
let $reactiveDeclaration,
138+
$$unsubscribe_reactiveDeclaration = noop,
139+
$$subscribe_reactiveDeclaration = () => ($$unsubscribe_reactiveDeclaration(), $$unsubscribe_reactiveDeclaration = subscribe(reactiveDeclaration, $$value => $$invalidate(3, $reactiveDeclaration = $$value)), reactiveDeclaration);
140+
141+
component_subscribe($$self, reactiveStoreVal, $$value => $$invalidate(2, $reactiveStoreVal = $$value));
142+
$$self.$$.on_destroy.push(() => $$unsubscribe_reactiveDeclaration());
143+
nonReactiveGlobal = Math.random();
144+
const reactiveConst = { x: Math.random() };
145+
reactiveModuleVar += 1;
146+
147+
if (Math.random()) {
148+
reactiveConst.x += 1;
149+
}
150+
151+
$$self.$$.update = () => {
152+
if ($$self.$$.dirty & /*reactiveModuleVar*/ 0) {
153+
$: $$subscribe_reactiveDeclaration($$invalidate(1, reactiveDeclaration = reactiveModuleVar * 2));
154+
}
155+
};
156+
157+
return [reactiveConst, reactiveDeclaration, $reactiveStoreVal, $reactiveDeclaration];
158+
}
159+
160+
class Component extends SvelteComponent {
161+
constructor(options) {
162+
super();
163+
init(this, options, instance, create_fragment, safe_not_equal, {});
164+
}
165+
}
166+
167+
export default Component;
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<script context="module">
2+
let nonReactiveModuleVar = Math.random();
3+
let reactiveModuleVar = Math.random();
4+
</script>
5+
6+
<script>
7+
import { reactiveStoreVal, unreactiveExport } from './store';
8+
9+
nonReactiveGlobal = Math.random();
10+
const reactiveConst = {x: Math.random()};
11+
12+
$: reactiveDeclaration = reactiveModuleVar * 2;
13+
14+
reactiveModuleVar += 1;
15+
if (Math.random()) {
16+
reactiveConst.x += 1;
17+
}
18+
</script>
19+
20+
<!--These should all get updaters because they have at least one reactive dependency-->
21+
<div class:update1={reactiveModuleVar}></div>
22+
<div class:update2={reactiveConst.x}></div>
23+
<div class:update3={nonReactiveGlobal && reactiveConst.x}></div>
24+
<div class:update4={$reactiveStoreVal}></div>
25+
<div class:update5={$reactiveDeclaration}></div>
26+
27+
<!--These shouldn't get updates because they're purely non-reactive-->
28+
<div class:static1={nonReactiveModuleVar}></div>
29+
<div class:static2={nonReactiveGlobal}></div>
30+
<div class:static3={nonReactiveModuleVar && nonReactiveGlobal}></div>
31+
<div class:static4={unreactiveExport}></div>
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
import { writable } from '../../../../store';
2+
3+
export const reactiveStoreVal = writable(0);
4+
export const unreactiveExport = true;

0 commit comments

Comments
 (0)