Skip to content

Improve performance of sidebar generation logic#3768

Merged
delucis merged 8 commits intomainfrom
chris/sidebar-perf
Mar 20, 2026
Merged

Improve performance of sidebar generation logic#3768
delucis merged 8 commits intomainfrom
chris/sidebar-perf

Conversation

@delucis
Copy link
Copy Markdown
Member

@delucis delucis commented Mar 19, 2026

Description

This PR refactors our sidebar generation logic to avoid using structuredClone() each time a sidebar is created. Especially on large sidebars, the clone can be expensive.

#2252 added the current sidebar approach and introduced the structured clone partially to defend against user mutations in component overrides. Since then, we refactored our route data system in #2390, which introduced klona to create a clone of the entire route data object. This means it is now safe to remove the extra structuredClone() in the sidebar logic.

The new strategy tracks the sidebar entries with isCurrent manually so we can patch those in a performant way on a single persistent object without relying on the structured clone to avoid mutations.

I haven’t tested on Cloudflare’s docs (mentioned in #3760) but I tested in Starlight’s docs:

  • Starlight docs: 1% performance increase (~178ms)
  • Starlight docs modified to add several thousand extra sidebar entries: 6% performance increase (~2.8s)

I would assume the increase should be even more significant in the CF docs given their high page count and sidebar size. And the fix here is essentially the same as the one tested in cloudflare/cloudflare-docs#28970structuredClone() was removed in both — this PR just avoids introducing some unnecessary code duplication and forking of code paths.

delucis added 3 commits March 19, 2026 18:18
Inspired by #3761 but with an implementation that is closer to the existing architecture and avoids some unnecessary code duplication.
@changeset-bot
Copy link
Copy Markdown

changeset-bot bot commented Mar 19, 2026

🦋 Changeset detected

Latest commit: 212bff1

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

This PR includes changesets to release 1 package
Name Type
@astrojs/starlight Patch

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

@netlify
Copy link
Copy Markdown

netlify bot commented Mar 19, 2026

Deploy Preview for astro-starlight ready!

Name Link
🔨 Latest commit 212bff1
🔍 Latest deploy log https://app.netlify.com/projects/astro-starlight/deploys/69bd88025dd61f000700e844
😎 Deploy Preview https://deploy-preview-3768--astro-starlight.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
Lighthouse
Lighthouse
1 paths audited
Performance: 100 (no change from production)
Accessibility: 100 (no change from production)
Best Practices: 100 (no change from production)
SEO: 100 (no change from production)
PWA: -
View the detailed breakdown and full score reports

To edit notification comments on pull requests, go to your Netlify project configuration.

@github-actions github-actions bot added the 🌟 core Changes to Starlight’s main package label Mar 19, 2026
@delucis delucis added the 🌟 patch Change that triggers a patch release label Mar 19, 2026
@astrobot-houston
Copy link
Copy Markdown
Contributor

astrobot-houston commented Mar 19, 2026

size-limit report 📦

Path Size
/index.html 5.61 KB (0%)
/_astro/*.js 26.03 KB (0%)
/_astro/*.css 16.04 KB (0%)

@delucis delucis added the pr-preview Trigger a preview release for this PR using pkg.pr.new label Mar 19, 2026
@github-actions github-actions bot removed the pr-preview Trigger a preview release for this PR using pkg.pr.new label Mar 19, 2026
@pkg-pr-new
Copy link
Copy Markdown

pkg-pr-new bot commented Mar 19, 2026

pnpm add https://pkg.pr.new/@astrojs/starlight@3768

commit: 5a877ea

matthewp
matthewp previously approved these changes Mar 19, 2026
ematipico
ematipico previously approved these changes Mar 20, 2026
Copy link
Copy Markdown
Member

@HiDeoo HiDeoo left a comment

Choose a reason for hiding this comment

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

Looks great to me 🔥 I left a few minor comments but nothing major.

I also tried experimenting with some further improvements regarding some string manipulations we do a lot when trying to find the current entry, e.g. pathsMatch(encodeURI(entry.href), pathname) which calls encodeURI once and neverPathFormatter twice for every entry in the sidebar until it finds the current one. But in the end, it didn't seem to make a significant difference in performance and it's already pretty fast even with large sidebars.

Co-Authored-By: HiDeoo <494699+HiDeoo@users.noreply.github.com>
@delucis delucis dismissed stale reviews from ematipico and matthewp via 7d294a0 March 20, 2026 12:35
Copy link
Copy Markdown
Member

@HiDeoo HiDeoo left a comment

Choose a reason for hiding this comment

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

Thanks for the updates, ready to 🚀

@delucis delucis merged commit a4c6c20 into main Mar 20, 2026
16 checks passed
@delucis delucis deleted the chris/sidebar-perf branch March 20, 2026 17:52
@astrobot-houston astrobot-houston mentioned this pull request Mar 20, 2026
dadezzz pushed a commit to dadezzz/ice-notes that referenced this pull request Mar 25, 2026
This PR contains the following updates:

| Package | Change | [Age](https://docs.renovatebot.com/merge-confidence/) | [Confidence](https://docs.renovatebot.com/merge-confidence/) |
|---|---|---|---|
| [@astrojs/starlight](https://starlight.astro.build) ([source](https://github.com/withastro/starlight/tree/HEAD/packages/starlight)) | [`0.38.1` → `0.38.2`](https://renovatebot.com/diffs/npm/@astrojs%2fstarlight/0.38.1/0.38.2) | ![age](https://developer.mend.io/api/mc/badges/age/npm/@astrojs%2fstarlight/0.38.2?slim=true) | ![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@astrojs%2fstarlight/0.38.1/0.38.2?slim=true) |

---

### Release Notes

<details>
<summary>withastro/starlight (@&#8203;astrojs/starlight)</summary>

### [`v0.38.2`](https://github.com/withastro/starlight/blob/HEAD/packages/starlight/CHANGELOG.md#0382)

[Compare Source](https://github.com/withastro/starlight/compare/@astrojs/starlight@0.38.1...@astrojs/starlight@0.38.2)

##### Patch Changes

- [#&#8203;3759](withastro/starlight#3759) [`f24ce99`](withastro/starlight@f24ce99) Thanks [@&#8203;MilesChou](https://github.com/MilesChou)! - Fixes an issue where monolingual sites using a region-specific locale (e.g., `zh-TW`) as the default would incorrectly display base language translations (e.g., `zh` Simplified Chinese) instead of the region-specific ones (e.g., `zh-TW` Traditional Chinese).

- [#&#8203;3768](withastro/starlight#3768) [`a4c6c20`](withastro/starlight@a4c6c20) Thanks [@&#8203;delucis](https://github.com/delucis)! - Improves performance of sidebar generation for sites with very large sidebars

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My44Ni4wIiwidXBkYXRlZEluVmVyIjoiNDMuODYuMCIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOltdfQ==-->

Co-authored-by: Renovate Bot <renovate@zarantonello.dev>
Co-committed-by: Renovate Bot <renovate@zarantonello.dev>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

🌟 core Changes to Starlight’s main package 🌟 patch Change that triggers a patch release

Projects

None yet

Development

Successfully merging this pull request may close these issues.

perf: sidebar trees are deep cloned on every page causes build overhead

5 participants