Skip to content

Commit aa0341c

Browse files
committed
Don't create a fragment at all for DOM-less components
1 parent 1324a57 commit aa0341c

File tree

22 files changed

+120
-111
lines changed

22 files changed

+120
-111
lines changed

src/compiler/compile/render_dom/Block.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -398,6 +398,21 @@ export default class Block {
398398
return body;
399399
}
400400

401+
has_content() {
402+
return this.renderer.options.dev ||
403+
this.first ||
404+
this.event_listeners.length > 0 ||
405+
this.chunks.intro.length > 0 ||
406+
this.chunks.outro.length > 0 ||
407+
this.chunks.create.length > 0 ||
408+
this.chunks.hydrate.length > 0 ||
409+
this.chunks.claim.length > 0 ||
410+
this.chunks.mount.length > 0 ||
411+
this.chunks.update.length > 0 ||
412+
this.chunks.destroy.length > 0 ||
413+
this.has_animation;
414+
}
415+
401416
render() {
402417
const key = this.key && this.get_unique_name('key');
403418

src/compiler/compile/render_dom/index.ts

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -241,11 +241,16 @@ export default function dom(
241241
args.push(x`$$props`, x`$$invalidate`);
242242
}
243243

244-
body.push(b`
245-
function create_fragment(#ctx) {
246-
${block.get_contents()}
247-
}
244+
const has_create_fragment = block.has_content();
245+
if (has_create_fragment) {
246+
body.push(b`
247+
function create_fragment(#ctx) {
248+
${block.get_contents()}
249+
}
250+
`);
251+
}
248252

253+
body.push(b`
249254
${component.extract_javascript(component.ast.module)}
250255
251256
${component.fully_hoisted}
@@ -437,7 +442,7 @@ export default function dom(
437442
438443
${css.code && b`this.shadowRoot.innerHTML = \`<style>${css.code.replace(/\\/g, '\\\\')}${options.dev ? `\n/*# sourceMappingURL=${css.map.toUrl()} */` : ''}</style>\`;`}
439444
440-
@init(this, { target: this.shadowRoot }, ${definition}, create_fragment, ${not_equal}, ${prop_names});
445+
@init(this, { target: this.shadowRoot }, ${definition}, ${has_create_fragment ? 'create_fragment': 'null'}, ${not_equal}, ${prop_names});
441446
442447
${dev_props_check}
443448
@@ -489,7 +494,7 @@ export default function dom(
489494
constructor(options) {
490495
super(${options.dev && `options`});
491496
${should_add_css && b`if (!@_document.getElementById("${component.stylesheet.id}-style")) ${add_css}();`}
492-
@init(this, options, ${definition}, create_fragment, ${not_equal}, ${prop_names});
497+
@init(this, options, ${definition}, ${has_create_fragment ? 'create_fragment': 'null'}, ${not_equal}, ${prop_names});
493498
${options.dev && b`@dispatch_dev("SvelteRegisterComponent", { component: this, tagName: "${name.name}", options, id: create_fragment.name });`}
494499
495500
${dev_props_check}

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

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -396,12 +396,12 @@ export default class InlineComponentWrapper extends Wrapper {
396396
`);
397397

398398
block.chunks.create.push(
399-
b`if (${name}) ${name}.$$.fragment.c();`
399+
b`if (${name}) @create_component(${name}.$$.fragment);`
400400
);
401401

402402
if (parent_nodes && this.renderer.options.hydratable) {
403403
block.chunks.claim.push(
404-
b`if (${name}) ${name}.$$.fragment.l(${parent_nodes});`
404+
b`if (${name}) @claim_component(${name}.$$.fragment, ${parent_nodes});`
405405
);
406406
}
407407

@@ -437,7 +437,7 @@ export default class InlineComponentWrapper extends Wrapper {
437437
${munged_bindings}
438438
${munged_handlers}
439439
440-
${name}.$$.fragment.c();
440+
@create_component(${name}.$$.fragment);
441441
@transition_in(${name}.$$.fragment, 1);
442442
@mount_component(${name}, ${update_mount_node}, ${anchor});
443443
} else {
@@ -472,11 +472,11 @@ export default class InlineComponentWrapper extends Wrapper {
472472
${munged_handlers}
473473
`);
474474

475-
block.chunks.create.push(b`${name}.$$.fragment.c();`);
475+
block.chunks.create.push(b`@create_component(${name}.$$.fragment);`);
476476

477477
if (parent_nodes && this.renderer.options.hydratable) {
478478
block.chunks.claim.push(
479-
b`${name}.$$.fragment.l(${parent_nodes});`
479+
b`@claim_component(${name}.$$.fragment, ${parent_nodes});`
480480
);
481481
}
482482

src/runtime/internal/Component.ts

Lines changed: 36 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,21 @@ import { blank_object, is_function, run, run_all, noop, has_prop } from './utils
44
import { children } from './dom';
55
import { transition_in } from './transitions';
66

7+
interface Fragment {
8+
key: string|null;
9+
first: null;
10+
/* create */ c: () => void;
11+
/* claim */ l: (nodes: any) => void;
12+
/* hydrate */ h: () => void;
13+
/* mount */ m: (target: HTMLElement, anchor: any) => void;
14+
/* update */ p: (changed: any, ctx: any) => void;
15+
/* measure */ r: () => void;
16+
/* fix */ f: () => void;
17+
/* animate */ a: () => void;
18+
/* intro */ i: (local: any) => void;
19+
/* outro */ o: (local: any) => void;
20+
/* destroy */ d: (detaching: 0|1) => void;
21+
}
722
// eslint-disable-next-line @typescript-eslint/class-name-casing
823
interface T$$ {
924
dirty: null;
@@ -13,7 +28,7 @@ interface T$$ {
1328
callbacks: any;
1429
after_update: any[];
1530
props: Record<string, 0 | string>;
16-
fragment: null|any;
31+
fragment: null|false|Fragment;
1732
not_equal: any;
1833
before_update: any[];
1934
context: Map<any, any>;
@@ -29,10 +44,18 @@ export function bind(component, name, callback) {
2944
}
3045
}
3146

47+
export function create_component(block) {
48+
block && block.c();
49+
}
50+
51+
export function claim_component(block, parent_nodes) {
52+
block && block.l(parent_nodes);
53+
}
54+
3255
export function mount_component(component, target, anchor) {
3356
const { fragment, on_mount, on_destroy, after_update } = component.$$;
3457

35-
fragment.m(target, anchor);
58+
fragment && fragment.m(target, anchor);
3659

3760
// onMount happens before the initial afterUpdate
3861
add_render_callback(() => {
@@ -51,15 +74,16 @@ export function mount_component(component, target, anchor) {
5174
}
5275

5376
export function destroy_component(component, detaching) {
54-
if (component.$$.fragment) {
55-
run_all(component.$$.on_destroy);
77+
const $$ = component.$$;
78+
if ($$.fragment !== null) {
79+
run_all($$.on_destroy);
5680

57-
component.$$.fragment.d(detaching);
81+
$$.fragment && $$.fragment.d(detaching);
5882

5983
// TODO null out other refs, including component.$$ (but need to
6084
// preserve final state?)
61-
component.$$.on_destroy = component.$$.fragment = null;
62-
component.$$.ctx = {};
85+
$$.on_destroy = $$.fragment = null;
86+
$$.ctx = {};
6387
}
6488
}
6589

@@ -115,15 +139,17 @@ export function init(component, options, instance, create_fragment, not_equal, p
115139
$$.update();
116140
ready = true;
117141
run_all($$.before_update);
118-
$$.fragment = create_fragment($$.ctx);
142+
143+
// `false` as a special case of no DOM component
144+
$$.fragment = create_fragment ? create_fragment($$.ctx) : false;
119145

120146
if (options.target) {
121147
if (options.hydrate) {
122148
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
123-
$$.fragment!.l(children(options.target));
149+
$$.fragment && $$.fragment!.l(children(options.target));
124150
} else {
125151
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
126-
$$.fragment!.c();
152+
$$.fragment && $$.fragment!.c();
127153
}
128154

129155
if (options.intro) transition_in(component.$$.fragment);

src/runtime/internal/scheduler.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,10 +70,10 @@ export function flush() {
7070
}
7171

7272
function update($$) {
73-
if ($$.fragment) {
73+
if ($$.fragment !== null) {
7474
$$.update($$.dirty);
7575
run_all($$.before_update);
76-
$$.fragment.p($$.dirty, $$.ctx);
76+
$$.fragment && $$.fragment.p($$.dirty, $$.ctx);
7777
$$.dirty = null;
7878

7979
$$.after_update.forEach(add_render_callback);

test/js/samples/component-static-array/expected.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import {
22
SvelteComponent,
3+
create_component,
34
destroy_component,
45
init,
56
mount_component,
@@ -15,7 +16,7 @@ function create_fragment(ctx) {
1516

1617
return {
1718
c() {
18-
nested.$$.fragment.c();
19+
create_component(nested.$$.fragment);
1920
},
2021
m(target, anchor) {
2122
mount_component(nested, target, anchor);

test/js/samples/component-static-immutable/expected.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import {
22
SvelteComponent,
3+
create_component,
34
destroy_component,
45
init,
56
mount_component,
@@ -15,7 +16,7 @@ function create_fragment(ctx) {
1516

1617
return {
1718
c() {
18-
nested.$$.fragment.c();
19+
create_component(nested.$$.fragment);
1920
},
2021
m(target, anchor) {
2122
mount_component(nested, target, anchor);

test/js/samples/component-static-immutable2/expected.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import {
22
SvelteComponent,
3+
create_component,
34
destroy_component,
45
init,
56
mount_component,
@@ -15,7 +16,7 @@ function create_fragment(ctx) {
1516

1617
return {
1718
c() {
18-
nested.$$.fragment.c();
19+
create_component(nested.$$.fragment);
1920
},
2021
m(target, anchor) {
2122
mount_component(nested, target, anchor);

test/js/samples/component-static-var/expected.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import {
22
SvelteComponent,
3+
create_component,
34
destroy_component,
45
detach,
56
element,
@@ -28,9 +29,9 @@ function create_fragment(ctx) {
2829

2930
return {
3031
c() {
31-
foo.$$.fragment.c();
32+
create_component(foo.$$.fragment);
3233
t0 = space();
33-
bar.$$.fragment.c();
34+
create_component(bar.$$.fragment);
3435
t1 = space();
3536
input = element("input");
3637
dispose = listen(input, "input", ctx.input_input_handler);

test/js/samples/component-static/expected.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import {
22
SvelteComponent,
3+
create_component,
34
destroy_component,
45
init,
56
mount_component,
@@ -15,7 +16,7 @@ function create_fragment(ctx) {
1516

1617
return {
1718
c() {
18-
nested.$$.fragment.c();
19+
create_component(nested.$$.fragment);
1920
},
2021
m(target, anchor) {
2122
mount_component(nested, target, anchor);

0 commit comments

Comments
 (0)