Improve rendering perf (#4956)

* Improve rendering perf

* Adding a changeset

* Disable eslint warning
This commit is contained in:
Matthew Phillips 2022-10-03 11:44:58 -04:00 committed by GitHub
parent a59731995b
commit ee8dd424fd
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 73 additions and 31 deletions

View file

@ -0,0 +1,5 @@
---
'astro': patch
---
Fix perf regression in SSR

View file

@ -45,35 +45,22 @@ export function stringifyChunk(result: SSRResult, chunk: string | RenderInstruct
} }
export class HTMLParts { export class HTMLParts {
public parts: Array<HTMLBytes | string>; public parts: string;
constructor() { constructor() {
this.parts = []; this.parts = ''
} }
append(part: string | HTMLBytes | RenderInstruction, result: SSRResult) { append(part: string | HTMLBytes | RenderInstruction, result: SSRResult) {
if (ArrayBuffer.isView(part)) { if (ArrayBuffer.isView(part)) {
this.parts.push(part); this.parts += decoder.decode(part);
} else { } else {
this.parts.push(stringifyChunk(result, part)); this.parts += stringifyChunk(result, part);
} }
} }
toString() { toString() {
let html = ''; return this.parts;
for (const part of this.parts) {
if (ArrayBuffer.isView(part)) {
html += decoder.decode(part);
} else {
html += part;
}
}
return html;
} }
toArrayBuffer() { toArrayBuffer() {
this.parts.forEach((part, i) => { return encoder.encode(this.parts);
if (!ArrayBuffer.isView(part)) {
this.parts[i] = encoder.encode(String(part));
}
});
return concatUint8Arrays(this.parts as Uint8Array[]);
} }
} }
@ -86,15 +73,3 @@ export function chunkToByteArray(
} }
return encoder.encode(stringifyChunk(result, chunk)); return encoder.encode(stringifyChunk(result, chunk));
} }
export function concatUint8Arrays(arrays: Array<Uint8Array>) {
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;
}

View file

@ -0,0 +1,7 @@
import { defineConfig } from 'astro/config';
import nodejs from '@astrojs/node';
export default defineConfig({
output: 'server',
adapter: nodejs()
});

View file

@ -0,0 +1,11 @@
{
"name": "@benchmark/simple",
"scripts": {
"start": "node server.mjs",
"build": "astro build"
},
"dependencies": {
"astro": "workspace:*",
"@astrojs/node": "workspace:*"
}
}

View file

@ -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`);

View file

@ -0,0 +1,8 @@
<html>
<head>
<title>{ Astro.props.title }</title>
</head>
<body>
<slot />
</body>
</html>

View file

@ -0,0 +1,9 @@
---
import Layout from '../components/Layout.astro';
const name = 'world';
---
<Layout title={`Index page`}>
<h1>index page</h1>
<h2>Hello { name }</h2>
</Layout>

View file

@ -1055,6 +1055,14 @@ importers:
astro: link:../../.. astro: link:../../..
vue: 3.2.40 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: packages/astro/test/fixtures/0-css:
specifiers: specifiers:
'@astrojs/react': workspace:* '@astrojs/react': workspace:*