From ee8dd424fda90688ff3f3ed4e736fb6151d9b422 Mon Sep 17 00:00:00 2001 From: Matthew Phillips Date: Mon, 3 Oct 2022 11:44:58 -0400 Subject: [PATCH] Improve rendering perf (#4956) * Improve rendering perf * Adding a changeset * Disable eslint warning --- .changeset/fifty-icons-smash.md | 5 +++ .../astro/src/runtime/server/render/common.ts | 37 +++---------------- .../test/benchmark/simple/astro.config.mjs | 7 ++++ .../astro/test/benchmark/simple/package.json | 11 ++++++ .../astro/test/benchmark/simple/server.mjs | 19 ++++++++++ .../simple/src/components/Layout.astro | 8 ++++ .../benchmark/simple/src/pages/index.astro | 9 +++++ pnpm-lock.yaml | 8 ++++ 8 files changed, 73 insertions(+), 31 deletions(-) create mode 100644 .changeset/fifty-icons-smash.md create mode 100644 packages/astro/test/benchmark/simple/astro.config.mjs create mode 100644 packages/astro/test/benchmark/simple/package.json create mode 100644 packages/astro/test/benchmark/simple/server.mjs create mode 100644 packages/astro/test/benchmark/simple/src/components/Layout.astro create mode 100644 packages/astro/test/benchmark/simple/src/pages/index.astro diff --git a/.changeset/fifty-icons-smash.md b/.changeset/fifty-icons-smash.md new file mode 100644 index 000000000..29dcc6354 --- /dev/null +++ b/.changeset/fifty-icons-smash.md @@ -0,0 +1,5 @@ +--- +'astro': patch +--- + +Fix perf regression in SSR diff --git a/packages/astro/src/runtime/server/render/common.ts b/packages/astro/src/runtime/server/render/common.ts index e64a18189..421546a46 100644 --- a/packages/astro/src/runtime/server/render/common.ts +++ b/packages/astro/src/runtime/server/render/common.ts @@ -45,35 +45,22 @@ export function stringifyChunk(result: SSRResult, chunk: string | RenderInstruct } export class HTMLParts { - public parts: Array; + public parts: string; constructor() { - this.parts = []; + this.parts = '' } append(part: string | HTMLBytes | RenderInstruction, result: SSRResult) { if (ArrayBuffer.isView(part)) { - this.parts.push(part); + this.parts += decoder.decode(part); } else { - this.parts.push(stringifyChunk(result, part)); + this.parts += stringifyChunk(result, part); } } toString() { - let html = ''; - for (const part of this.parts) { - if (ArrayBuffer.isView(part)) { - html += decoder.decode(part); - } else { - html += part; - } - } - return html; + return this.parts; } toArrayBuffer() { - this.parts.forEach((part, i) => { - if (!ArrayBuffer.isView(part)) { - this.parts[i] = encoder.encode(String(part)); - } - }); - return concatUint8Arrays(this.parts as Uint8Array[]); + return encoder.encode(this.parts); } } @@ -86,15 +73,3 @@ export function chunkToByteArray( } return encoder.encode(stringifyChunk(result, chunk)); } - -export function concatUint8Arrays(arrays: Array) { - let len = 0; - arrays.forEach((arr) => (len += arr.length)); - let merged = new Uint8Array(len); - let offset = 0; - arrays.forEach((arr) => { - merged.set(arr, offset); - offset += arr.length; - }); - return merged; -} diff --git a/packages/astro/test/benchmark/simple/astro.config.mjs b/packages/astro/test/benchmark/simple/astro.config.mjs new file mode 100644 index 000000000..da503f3ba --- /dev/null +++ b/packages/astro/test/benchmark/simple/astro.config.mjs @@ -0,0 +1,7 @@ +import { defineConfig } from 'astro/config'; +import nodejs from '@astrojs/node'; + +export default defineConfig({ + output: 'server', + adapter: nodejs() +}); diff --git a/packages/astro/test/benchmark/simple/package.json b/packages/astro/test/benchmark/simple/package.json new file mode 100644 index 000000000..d54f76f90 --- /dev/null +++ b/packages/astro/test/benchmark/simple/package.json @@ -0,0 +1,11 @@ +{ + "name": "@benchmark/simple", + "scripts": { + "start": "node server.mjs", + "build": "astro build" + }, + "dependencies": { + "astro": "workspace:*", + "@astrojs/node": "workspace:*" + } +} diff --git a/packages/astro/test/benchmark/simple/server.mjs b/packages/astro/test/benchmark/simple/server.mjs new file mode 100644 index 000000000..e5844d60c --- /dev/null +++ b/packages/astro/test/benchmark/simple/server.mjs @@ -0,0 +1,19 @@ +import http from 'http'; +import { handler } from './dist/server/entry.mjs'; + +const listener = (req, res) => { + handler(req, res, err => { + if(err) { + res.writeHead(500); + res.end(err.toString()); + } else { + res.writeHead(404); + res.end('Not found'); + } + }); +}; + +const server = http.createServer(listener); +server.listen(3002); +// eslint-disable-next-line no-console +console.log(`Listening at http://localhost:3002`); diff --git a/packages/astro/test/benchmark/simple/src/components/Layout.astro b/packages/astro/test/benchmark/simple/src/components/Layout.astro new file mode 100644 index 000000000..c8a65f26e --- /dev/null +++ b/packages/astro/test/benchmark/simple/src/components/Layout.astro @@ -0,0 +1,8 @@ + + + { Astro.props.title } + + + + + diff --git a/packages/astro/test/benchmark/simple/src/pages/index.astro b/packages/astro/test/benchmark/simple/src/pages/index.astro new file mode 100644 index 000000000..ee287144f --- /dev/null +++ b/packages/astro/test/benchmark/simple/src/pages/index.astro @@ -0,0 +1,9 @@ +--- +import Layout from '../components/Layout.astro'; +const name = 'world'; +--- + + +

index page

+

Hello { name }

+
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 9d1fdfcd8..0e906a047 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1055,6 +1055,14 @@ importers: astro: link:../../.. vue: 3.2.40 + packages/astro/test/benchmark/simple: + specifiers: + '@astrojs/node': workspace:* + astro: workspace:* + dependencies: + '@astrojs/node': link:../../../../integrations/node + astro: link:../../.. + packages/astro/test/fixtures/0-css: specifiers: '@astrojs/react': workspace:*