Skip to content

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

@MohamedH1998

Description

@MohamedH1998

What version of starlight are you using?

0.37.6

What version of astro are you using?

5.13.7

What package manager are you using?

npm

What operating system are you using?

Mac

What browser are you using?

Chrome

Describe the Bug

In our developer docs, we have 7,303 pages and currently and our local builds are currently taking 350-400 seconds (locally) - after profiling, we found that for every page rendered, Starlight deep-clones the entire sidebar trees - with large 7,303 pages and a large sidebar this adds up.

Metric Value
structuredClone self-time 41.8s
Measured build time saving after fix ~49–56s (~14%)

What's happening

Every page triggers a full structuredClone of the entire intermediate sidebar tree inside getSidebarFromIntermediateSidebar (utils/navigation.ts:409). The only thing done with that clone is flipping isCurrent: true on a single link entry to mark the current page.
Immediately after, a second full clone of the entire route data (including the sidebar) is made via klona(routeData) in the middleware pipeline - and this is the copy that components actually read from.
Clone 1 is redundant in static builds. The klona in middleware already provides full isolation for all downstream consumers. The structuredClone exists solely to prevent mutating the cached sidebar — a concern that can be solved with a simple in-place set/reset of one boolean.

Proposed fix

Add an internal non-exported fast path (getSidebarForRender) gated on config.prerender === true that replaces structuredClone with an in-place set/reset of isCurrent. Static builds are sequential — there is no concurrent access risk. The exported getSidebar() and getSidebarFromConfig() APIs are unchanged in all modes. Only the internal render pipeline takes the fast path.

Link to Minimal Reproducible Example

N/A

Participation

  • I am willing to submit a pull request for this issue.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions