Skip to content

perf(web): load the bootstrap and the first issue page together - #243

Merged
imshashank merged 2 commits into
mainfrom
perf/bootstrap-parallel
Aug 8, 2026
Merged

perf(web): load the bootstrap and the first issue page together#243
imshashank merged 2 commits into
mainfrom
perf/bootstrap-parallel

Conversation

@imshashank

@imshashank imshashank commented Aug 8, 2026

Copy link
Copy Markdown
Contributor

Follow-up to #242, on the same hard-load path.

The problem

dehydratedWorkspace waited for the entire bootstrap payload before it started fetching the first issue page, because it read activeTeamId off the finished payload:

const bootstrap = await serverBootstrap(principal);
const teamId = bootstrap.activeTeamId;
if (teamId !== null) { ... await serverIssuePage(principal, teamId) }

The issue list is the heaviest query in the dehydrated state, and it sat behind six queries it does not depend on.

The change

Only the team list decides which team is active, so that is the one thing the issue page actually waits on.

  • bootstrapTeams resolves the teams and the active team.
  • bootstrapPayloadFor builds the rest from an already-resolved team list.
  • bootstrapPayload composes the two, so /api/bootstrap is unchanged.

dehydratedWorkspace now resolves the team once and runs the rest of the bootstrap alongside the issue page.

No query is repeated. The team list is fetched once and handed to both halves, so this removes a round trip from the critical path without adding one anywhere else.

Tests

Three new tests in apps/web/tests/lib/query/prefetch.test.ts. They hold each loader open and assert what has started, so re-serialising fails them.

Verified by mutation. Against the previous sequential version all three fail, the direct one immediately:

(fail) resolves the active team before anything that needs it
(fail) loads the rest of the bootstrap and the first issue page concurrently
(fail) dehydrates both the bootstrap and the issue list
 0 pass
 3 fail

Full web suite on this branch: 1583 pass, 0 fail.

Greptile Summary

The PR shortens the hard-load critical path by resolving the active team first, then loading the remaining bootstrap data and initial issue page concurrently.

  • Splits team resolution from construction of the remaining bootstrap payload.
  • Preserves the existing /api/bootstrap composition.
  • Adds controlled concurrency and dehydration tests for the workspace prefetch path.

Confidence Score: 5/5

The PR appears safe to merge.

No blocking failure remains.

Important Files Changed

Filename Overview
apps/web/src/lib/api/bootstrap.ts Separates authorized team resolution from the remaining payload construction while preserving the existing composed bootstrap API.
apps/web/src/lib/query/prefetch.ts Runs bootstrap payload construction and the active team's initial issue-page request concurrently, then caches both results.
apps/web/tests/lib/query/prefetch.test.ts Adds held-promise tests that verify team-first sequencing, concurrent loading, and dehydration of both query roots.

Sequence Diagram

sequenceDiagram
    participant W as dehydratedWorkspace
    participant T as bootstrapTeams
    participant B as bootstrapPayloadFor
    participant I as serverIssuePage
    participant Q as QueryClient
    W->>T: Resolve teams and active team
    T-->>W: BootstrapTeams
    par Remaining bootstrap
        W->>B: Build payload from resolved teams
        B-->>W: Bootstrap payload
    and Initial issue page
        W->>I: Fetch active team's issues
        I-->>W: Issue page
    end
    W->>Q: Cache bootstrap and issue page
    W-->>W: Dehydrate query state
Loading

Reviews (2): Last reviewed commit: "Merge main into perf/bootstrap-parallel" | Re-trigger Greptile

dehydratedWorkspace waited for the whole bootstrap before it started the
first issue page, because it read the active team id off the finished
payload. The issue list is the heaviest query in the dehydrated state and
it sat behind six that it does not depend on.

Only the team list decides which team is active, so split that out.
bootstrapTeams resolves teams and the active team, bootstrapPayloadFor
builds the rest from that, and bootstrapPayload composes the two so the
route handler is unchanged. dehydratedWorkspace then resolves the team
once and runs the rest of the bootstrap and the issue page together.

No query is repeated: the team list is fetched once and handed to both.
@imshashank
imshashank requested a review from pulkitxm as a code owner August 8, 2026 16:15
@vercel

vercel Bot commented Aug 8, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
orbit Ready Ready Preview Aug 8, 2026 4:56pm

Request Review

@github-actions github-actions Bot added tests Test coverage and test infrastructure area: web The Next.js app and its UI labels Aug 8, 2026
@coderabbitai

coderabbitai Bot commented Aug 8, 2026

Copy link
Copy Markdown

Warning

Review limit reached

@imshashank, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 5 minutes

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 99449f27-0612-49e1-86de-e82ade91cf6d

📥 Commits

Reviewing files that changed from the base of the PR and between 409bf8a and 7766ad2.

📒 Files selected for processing (3)
  • apps/web/src/lib/api/bootstrap.ts
  • apps/web/src/lib/query/prefetch.ts
  • apps/web/tests/lib/query/prefetch.test.ts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@imshashank
imshashank merged commit 26e2dcb into main Aug 8, 2026
12 checks passed
@imshashank
imshashank deleted the perf/bootstrap-parallel branch August 8, 2026 17:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: web The Next.js app and its UI tests Test coverage and test infrastructure

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant