-
-
Notifications
You must be signed in to change notification settings - Fork 3.8k
perf(runtime): improve rendering performance #17857
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 35 commits
d6ac9cb
a582d91
1f00ef4
e9a12e7
caba2ac
b967c4b
16c740b
c80520a
2af0b37
d6dd1bb
66fe4cd
ac98cce
754af93
6384af0
f6011b1
b4c0c30
b5d2c84
7dcb475
7f61a85
2c98f41
6d0679b
d758231
c84b821
a1ffad0
f4bc28a
60a1a0d
30c5de8
8ef51e6
081366d
af61a47
1c1a6e0
4e3b153
e518435
dc81a5a
92395ce
8514d2b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| --- | ||
| 'astro': patch | ||
| --- | ||
|
|
||
| Improves server-side rendering performance | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,8 +1,35 @@ | ||
| import { escape } from 'html-escaper'; | ||
|
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I know, I know, this is scary, however the code here is incredibly hot (🔥 🔥), and as such it needs a very fast HTML escape solution. This code is between 2 to 3 times as fast depending on the workload and is really similar (albeit slightly tuned to Astro's use case) to rising stars libraries like https://github.com/SukkaW/fast-escape-html In a further PR, I'd like to perhaps remove that dep completely and have our own escape.ts somewhere that we re-use.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I am not worried about "being scary", but maybe this change should be part of its own PR:
|
||
| import { streamAsyncIterator } from './util.js'; | ||
|
|
||
| // Leverage the battle-tested `html-escaper` npm package. | ||
| export const escapeHTML = escape; | ||
| const ESCAPABLE = /[&<>'"]/g; | ||
|
|
||
| function entityFor(code: number): string { | ||
| switch (code) { | ||
| case 38: | ||
| return '&'; | ||
| case 60: | ||
| return '<'; | ||
| case 62: | ||
| return '>'; | ||
| case 39: | ||
| return '''; | ||
| default: | ||
| return '"'; | ||
| } | ||
| } | ||
|
|
||
| export function escapeHTML(value: string): string { | ||
| ESCAPABLE.lastIndex = 0; | ||
| if (!ESCAPABLE.test(value)) return value; | ||
| let output = ''; | ||
| let last = 0; | ||
| do { | ||
| const index = ESCAPABLE.lastIndex - 1; | ||
| if (last !== index) output += value.slice(last, index); | ||
| output += entityFor(value.charCodeAt(index)); | ||
| last = index + 1; | ||
| } while (ESCAPABLE.test(value)); | ||
| return last === value.length ? output : output + value.slice(last); | ||
| } | ||
|
|
||
| /** | ||
| * Serializes a value to a JSON string that is safe to embed inside a `<script>` tag. | ||
|
|
@@ -36,9 +63,9 @@ const htmlStringSymbol = Symbol.for('astro:html-string'); | |
| * A "blessed" extension of String that tells Astro that the string | ||
| * has already been escaped. This helps prevent double-escaping of HTML. | ||
| */ | ||
| export class HTMLString extends String { | ||
| [htmlStringSymbol] = true; | ||
| } | ||
| export class HTMLString extends String {} | ||
|
|
||
| Object.defineProperty(HTMLString.prototype, htmlStringSymbol, { value: true }); | ||
|
|
||
| type BlessedType = string | HTMLBytes; | ||
|
|
||
|
|
@@ -64,7 +91,7 @@ export const markHTMLString = (value: any) => { | |
| }; | ||
|
|
||
| export function isHTMLString(value: any): value is HTMLString { | ||
| return !!value?.[htmlStringSymbol]; | ||
| return typeof value === 'object' && value !== null && value[htmlStringSymbol] === true; | ||
| } | ||
|
|
||
| function markHTMLBytes(bytes: Uint8Array) { | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.