From d3cc92c9172aecbb4836397b1fb6878df84684bf Mon Sep 17 00:00:00 2001 From: Cory Virok Date: Tue, 17 May 2022 02:09:53 -0700 Subject: [PATCH] Implemented a runtime optimization for SSR. 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. --- src/compiler/compile/render_ssr/Renderer.ts | 41 +++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/src/compiler/compile/render_ssr/Renderer.ts b/src/compiler/compile/render_ssr/Renderer.ts index 64e9ee1f4e..3abefc8fdd 100644 --- a/src/compiler/compile/render_ssr/Renderer.ts +++ b/src/compiler/compile/render_ssr/Renderer.ts @@ -106,6 +106,11 @@ export default class Renderer { this.current = last.current; } + // Optimize the TemplateLiteral to remove unnecessary nodes + // that both increase code size but also add additional and + // unnecessary string formatting at runtime. + collapse_literal(popped.literal) + return popped.literal; } @@ -121,3 +126,39 @@ export default class Renderer { }); } } + +// Collapse string literals together +function collapse_literal(literal: TemplateLiteral) { + if (literal.quasis.length) { + // flatMap() to produce an array containing [quasi, expr, quasi, expr, ..., quasi] + const zip = literal.quasis.reduce((acc, cur, index) => { + const expr = literal.expressions[index] + acc.push(cur) + if (expr) { + acc.push(expr) + } + return acc + }, []); + + // If an expression is a simple string literal, combine it with its preceeding + // and following quasi + let curQuasi = zip[0] + const newZip = [curQuasi] + for (let i = 1; i < zip.length; i += 2) { + const expr = zip[i] + const nextQuasi = zip[i + 1] + if (expr.type === 'Literal' && typeof expr.value === 'string') { + curQuasi.value.raw += escape_template(expr.value) + nextQuasi.value.raw + } else { + newZip.push(expr) + newZip.push(nextQuasi) + curQuasi = nextQuasi + } + } + + // Reconstitute the quasi and expressions arrays + literal.quasis = newZip.filter((_, index) => index % 2 === 0) + literal.expressions = newZip.filter((_, index) => index % 2 === 1) + } + +}