Skip to content

perf(runtime): improve rendering performance - #17857

Merged
Princesseuh merged 36 commits into
mainfrom
perf/server-render-allocations
Sep 9, 2026
Merged

perf(runtime): improve rendering performance#17857
Princesseuh merged 36 commits into
mainfrom
perf/server-render-allocations

Conversation

@Princesseuh

@Princesseuh Princesseuh commented Aug 29, 2026

Copy link
Copy Markdown
Member

Changes

This PR improves the overall performance of our rendering pipeline, without changing the entire structure or anything, just mostly focused on reducing allocations, preventing V8 de-opt, and/or just faster code in some places.

This of course mostly improves SSR performance, but nonetheless, in local this makes the docs build 2s faster on my computer. In SSR stress benchmarks, this has resulted in a up to 70% improvement in raw ops/s, but it's of course not representing real work.

Testing

Tests should pass. Also added some tests for behavior that I found easy to regress by accident while working on this.

Docs

N/A

@changeset-bot

changeset-bot Bot commented Aug 29, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 8514d2b

The changes in this PR will be included in the next version bump.

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@github-actions github-actions Bot added the pkg: astro Related to the core `astro` package (scope) label Aug 29, 2026
@codspeed-hq

codspeed-hq Bot commented Aug 29, 2026

Copy link
Copy Markdown

Merging this PR will improve performance by 30.93%

⚠️ Different runtime environments detected

Some benchmarks with significant performance changes were compared across different runtime environments,
which may affect the accuracy of the results.

Open the report in CodSpeed to investigate

⚡ 9 improved benchmarks
✅ 12 untouched benchmarks

Performance Changes

Benchmark BASE HEAD Efficiency
large-array (BufferedRenderer per child) 194.9 ms 121 ms +61.05%
many-slots (eager slot prerendering) 6.5 ms 4.4 ms +49.51%
large-array [streaming] 164.4 ms 112.7 ms +45.88%
many-components [streaming] 8.2 ms 5.7 ms +43.54%
many-components (markHTMLString, isHTMLString, validateProps) 9.6 ms 7.5 ms +28.15%
Rendering: streaming [true], .astro file 208.8 ms 165.7 ms +25.98%
many-expressions [streaming] 13.7 ms 12.2 ms +12.28%
Rendering: streaming [false], .astro file 198.8 ms 177.7 ms +11.89%
many-expressions (renderChild dispatch, escapeHTML) 14.8 ms 13.4 ms +10.58%

Tip

Curious why performance improved? Comment @codspeedbot explain why performance improved on this PR, or directly use the CodSpeed MCP with your agent.


Comparing perf/server-render-allocations (8514d2b) with main (2fc7ce9)1

Open in CodSpeed

Footnotes

  1. No successful run was found on main (de5cc2d) during the generation of this report, so 2fc7ce9 was used instead as the comparison base. There might be some changes unrelated to this pull request in this report.

@Princesseuh
Princesseuh force-pushed the perf/server-render-allocations branch 6 times, most recently from 400137f to e609ba6 Compare September 3, 2026 17:30
@@ -1,8 +1,35 @@
import { escape } from 'html-escaper';

@Princesseuh Princesseuh Sep 7, 2026

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The 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.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The 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:

  • if we break something, we can revert only this change
  • this PR doesn't have a test suite to cover the dep we're removing (we assume it's tested)

@Princesseuh
Princesseuh marked this pull request as ready for review September 7, 2026 13:10
@Princesseuh Princesseuh changed the title perf(runtime): reduce server-side render allocations perf(runtime): improve rendering performance Sep 7, 2026
@ematipico ematipico added the pr: astro-review Triggers a bot to do an automated review label Sep 7, 2026
@astro-factory astro-factory Bot removed the pr: astro-review Triggers a bot to do an automated review label Sep 7, 2026

@ematipico ematipico left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The changes make sense. I suggested to move the HTML escape into its own PR. Let's wait for when Matthew comes back, I would like his review too

Comment thread .changeset/fresh-otters-run.md Outdated
Comment thread packages/astro/src/runtime/server/render/astro/instance.ts Outdated
Comment thread packages/astro/src/runtime/server/render/util.ts Outdated
@@ -1,8 +1,35 @@
import { escape } from 'html-escaper';

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The 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:

  • if we break something, we can revert only this change
  • this PR doesn't have a test suite to cover the dep we're removing (we assume it's tested)

@astro-factory astro-factory Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No findings.

Merge Requirement Assessment

Status: satisfied

  • Improve SSR rendering performance by reducing allocations, avoiding V8 deopts, and using faster rendering paths — implemented across packages/astro/src/runtime/server/ (escape, render-child dispatch, template-result rendering, streaming engine, attribute spreading, slot handling, fetch-state slots) and covered by dedicated regression tests for frozen Astro globals, frozen render instructions, hydration attribute escaping, thenable-versus-render-instance precedence, and sync subtree expansion.

Questions

None.

Review Status

Verdict: ready to merge based on static review
Context: PR #17857 (#17857)
Scope: full PR diff (22 files) at head 70824a3c928e4421190d71d4d79d00fe423ab41d against base 92f23cc121d3a1a03c6fb901a519309662b333de
Changeset: present and covers astro
Limitations: none
Validation: Static review only; no project code, tests, builds, or checks were run.
GitHub context: collected
Git scope: PR base/head verified via read-only GitHub tools; 0 unresolved prior review threads.

This review was made by an LLM. The analysis may be wrong, and reports might be incorrect.

@Princesseuh

Princesseuh commented Sep 7, 2026

Copy link
Copy Markdown
Member Author

@ematipico We have several tests for HTML escaping, https://github.com/withastro/astro/blob/9870f95601690d9d98799b6fa78a0bc76165ee06/packages/astro/test/html-escape.test.ts https://github.com/withastro/astro/blob/9870f95601690d9d98799b6fa78a0bc76165ee06/packages/astro/test/units/render/escape.test.ts

and a few more elsewhere. The code there has already changed through times between a custom version vs the dep vs other stuff

@ematipico

Copy link
Copy Markdown
Member

LOL the package has like 4 tests 🤣

Comment thread packages/astro/src/core/fetch/fetch-state.ts
return markHTMLString(content);
}

const HEAD_INSTRUCTION = Object.freeze(

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

bonus points for using Object.freeze

@Princesseuh
Princesseuh force-pushed the perf/server-render-allocations branch from ab3f880 to dc81a5a Compare September 9, 2026 14:41
Comment thread packages/astro/src/core/fetch/fetch-state.ts Outdated
Comment thread packages/astro/src/runtime/server/render/util.ts Outdated
@Princesseuh
Princesseuh merged commit 2637ed1 into main Sep 9, 2026
29 checks passed
@Princesseuh
Princesseuh deleted the perf/server-render-allocations branch September 9, 2026 16:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

docs pr pkg: astro Related to the core `astro` package (scope)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants