From 32a94fcfc5b119d8cc142d6489e308381f26ccc2 Mon Sep 17 00:00:00 2001 From: Cory Virok Date: Mon, 27 Feb 2023 07:32:45 -0800 Subject: [PATCH 01/18] chore: implemented a small runtime optimization for SSR (#7539) Prior to this change, the compiler would generate a template literal that had many purely static string variables nested within it. This change collapses these static strings into the surrounding template literal which should result in (minor) size and performance improvements for the SSR generated code. --------- Co-authored-by: Simon H <5968653+dummdidumm@users.noreply.github.com> Co-authored-by: Simon Holthausen --- src/compiler/compile/render_ssr/Renderer.ts | 4 +++ .../utils/collapse_template_literal.ts | 34 +++++++++++++++++++ .../samples/collapse-literal-ssr/_config.js | 6 ++++ .../samples/collapse-literal-ssr/expected.js | 25 ++++++++++++++ .../samples/collapse-literal-ssr/input.svelte | 20 +++++++++++ .../samples/assignment-to-const-5/errors.json | 9 ++--- .../samples/assignment-to-const-7/errors.json | 9 ++--- 7 files changed, 95 insertions(+), 12 deletions(-) create mode 100644 src/compiler/compile/utils/collapse_template_literal.ts create mode 100644 test/js/samples/collapse-literal-ssr/_config.js create mode 100644 test/js/samples/collapse-literal-ssr/expected.js create mode 100644 test/js/samples/collapse-literal-ssr/input.svelte diff --git a/src/compiler/compile/render_ssr/Renderer.ts b/src/compiler/compile/render_ssr/Renderer.ts index 64e9ee1f4e..99a2ee3d68 100644 --- a/src/compiler/compile/render_ssr/Renderer.ts +++ b/src/compiler/compile/render_ssr/Renderer.ts @@ -16,6 +16,7 @@ import Title from './handlers/Title'; import { AppendTarget, CompileOptions } from '../../interfaces'; import { INode } from '../nodes/interfaces'; import { Expression, TemplateLiteral, Identifier } from 'estree'; +import { collapse_template_literal } from '../utils/collapse_template_literal'; import { escape_template } from '../utils/stringify'; type Handler = (node: any, renderer: Renderer, options: CompileOptions) => void; @@ -106,6 +107,9 @@ export default class Renderer { this.current = last.current; } + // Optimize the TemplateLiteral to remove unnecessary nodes + collapse_template_literal(popped.literal); + return popped.literal; } diff --git a/src/compiler/compile/utils/collapse_template_literal.ts b/src/compiler/compile/utils/collapse_template_literal.ts new file mode 100644 index 0000000000..5c5f78b8a3 --- /dev/null +++ b/src/compiler/compile/utils/collapse_template_literal.ts @@ -0,0 +1,34 @@ +import { TemplateLiteral } from 'estree'; +import { escape_template } from './stringify'; + +/** + * Collapse string literals together + */ +export function collapse_template_literal(literal: TemplateLiteral) { + if (!literal.quasis.length) return; + + const collapsed_quasis = []; + const collapsed_expressions = []; + + let cur_quasi = literal.quasis[0]; + + // An expression always follows a quasi and vice versa, ending with a quasi + for (let i = 0; i < literal.quasis.length; i++) { + const expr = literal.expressions[i]; + const next_quasi = literal.quasis[i + 1]; + // If an expression is a simple string literal, combine it with its preceding + // and following quasi + if (next_quasi && expr && expr.type === 'Literal' && typeof expr.value === 'string') { + cur_quasi.value.raw += escape_template(expr.value) + next_quasi.value.raw; + } else { + if (expr) { + collapsed_expressions.push(expr); + } + collapsed_quasis.push(cur_quasi); + cur_quasi = next_quasi; + } + } + + literal.quasis = collapsed_quasis; + literal.expressions = collapsed_expressions; +} diff --git a/test/js/samples/collapse-literal-ssr/_config.js b/test/js/samples/collapse-literal-ssr/_config.js new file mode 100644 index 0000000000..c4070b9a3b --- /dev/null +++ b/test/js/samples/collapse-literal-ssr/_config.js @@ -0,0 +1,6 @@ +export default { + options: { + generate: 'ssr', + dev: true + } +}; diff --git a/test/js/samples/collapse-literal-ssr/expected.js b/test/js/samples/collapse-literal-ssr/expected.js new file mode 100644 index 0000000000..8440a10082 --- /dev/null +++ b/test/js/samples/collapse-literal-ssr/expected.js @@ -0,0 +1,25 @@ +/* generated by Svelte vX.Y.Z */ +import { add_attribute, create_ssr_component, escape } from "svelte/internal"; + +const const1 = 1; +const const2 = 'const2'; + +function foo() { + return ''; +} + +const Component = create_ssr_component(($$result, $$props, $$bindings, slots) => { + return ` +
-
+ + +- +- + + +
-
+
-
+
-
`; +}); + +export default Component; \ No newline at end of file diff --git a/test/js/samples/collapse-literal-ssr/input.svelte b/test/js/samples/collapse-literal-ssr/input.svelte new file mode 100644 index 0000000000..83a7be9bda --- /dev/null +++ b/test/js/samples/collapse-literal-ssr/input.svelte @@ -0,0 +1,20 @@ + + + +
-
+ + +
-
+
-
+ + +
-
+
-
+
-
diff --git a/test/validator/samples/assignment-to-const-5/errors.json b/test/validator/samples/assignment-to-const-5/errors.json index 21de70863c..bca92bf266 100644 --- a/test/validator/samples/assignment-to-const-5/errors.json +++ b/test/validator/samples/assignment-to-const-5/errors.json @@ -4,14 +4,11 @@ "message": "You are assigning to a const", "start": { "line": 3, - "column": 1, - "character": 31 + "column": 1 }, "end": { "line": 3, - "column": 33, - "character": 63 - }, - "pos": 31 + "column": 33 + } } ] \ No newline at end of file diff --git a/test/validator/samples/assignment-to-const-7/errors.json b/test/validator/samples/assignment-to-const-7/errors.json index 34c88bebf6..5304a61c4b 100644 --- a/test/validator/samples/assignment-to-const-7/errors.json +++ b/test/validator/samples/assignment-to-const-7/errors.json @@ -4,14 +4,11 @@ "message": "You are assigning to a const", "start": { "line": 3, - "column": 1, - "character": 43 + "column": 1 }, "end": { "line": 3, - "column": 42, - "character": 84 - }, - "pos": 43 + "column": 42 + } } ] \ No newline at end of file From b5ec863a0ea4ed7334b46850f68d9942cdaa333a Mon Sep 17 00:00:00 2001 From: Simon H <5968653+dummdidumm@users.noreply.github.com> Date: Mon, 27 Feb 2023 17:13:50 +0100 Subject: [PATCH 02/18] chore: update changelog --- CHANGELOG.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 603c80cbbf..3fb3d751d6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ * Add a11y warnings: * `aria-activedescendant-has-tabindex`: elements with `aria-activedescendant` need to have a `tabindex` ([#8172](https://github.com/sveltejs/svelte/pull/8172)) + * `role-supports-aria-props`: checks that the (implicit) element role supports the given aria attributes ([#8195](https://github.com/sveltejs/svelte/pull/8195)) * Omit a11y warning on `