perf(frontend): stop serialising independent requests during app init - #321
perf(frontend): stop serialising independent requests during app init#321HAAHIT wants to merge 1 commit into
Conversation
Signing in ran four requests strictly one after another, each waiting on the
full round trip of the one before:
/api/workspaces -> /api/workspaces/invites/me -> /api/state -> /api/schema
Only two of those links are real dependencies. Two fixes:
/api/workspaces and /api/workspaces/invites/me are independent. The invites
endpoint depends only on get_current_user and needs nothing from the workspace
list -- the old code even issued it before activeWorkspace was assigned, so it
could never have been using it. Awaiting them in sequence cost a full extra
round trip on every app load. Promise.all now runs them together.
/api/schema is no longer awaited before navigating. It only feeds the chat UI,
which already declares realSchema as SchemaTable[] | null, initialises it to
null, and whose components default the prop to null -- so the next screen
renders fine without it and fills in when it arrives. Awaiting it held up both
isLoaded and the redirect, leaving the user on a loading screen waiting for
data that screen did not need. It now loads in the background through the
existing fetchSchemaAsync helper rather than a second copy of that logic.
The serial chain drops from four round trips to two, and the second of those
no longer blocks the redirect.
svelte-check reports 0 errors and the production build succeeds.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
🤖 CodeAnt AI — Review Status
|
|
Warning Review limit reached
Next review available in: 32 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 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 configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (1)
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. Comment |
| const [workspaces, invites] = await Promise.all([ | ||
| apiCall("/api/workspaces"), | ||
| apiCall("/api/workspaces/invites/me"), | ||
| ]); |
There was a problem hiding this comment.
Suggestion: The combined promise makes workspace initialization fail as a unit when the independent invitations request returns an error. Because neither result is assigned until both requests resolve, a successful workspace response is discarded and callers can continue with an empty or stale workspaces list and no activeWorkspace. Handle the two requests independently so an invitations failure does not prevent workspace loading. [logic error]
Severity Level: Major ⚠️
- ❌ Workspace navigation can fail when invitation loading errors.
- ⚠️ Successful workspace responses are discarded during partial failures.
- ⚠️ Users may be redirected with no active workspace.(Use Cmd/Ctrl + Click for best experience)
Prompt for AI Agent 🤖
This is a comment left during a code review.
**Path:** frontend/src/lib/appState.svelte.ts
**Line:** 76:79
**Comment:**
*Logic Error: The combined promise makes workspace initialization fail as a unit when the independent invitations request returns an error. Because neither result is assigned until both requests resolve, a successful workspace response is discarded and callers can continue with an empty or stale `workspaces` list and no `activeWorkspace`. Handle the two requests independently so an invitations failure does not prevent workspace loading.
Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix| // Awaiting it here held up isLoaded and the redirect below for a whole | ||
| // round trip, so the user sat on a loading screen waiting for data | ||
| // that the next screen does not need in order to appear. | ||
| void this.fetchSchemaAsync(); |
There was a problem hiding this comment.
Suggestion: Starting the schema request without awaiting or associating it with the current database allows its response to update realSchema after the user switches databases or logs out. fetchSchemaAsync() assigns the response unconditionally, so an older request can overwrite the newly selected database's schema or repopulate schema after logout. Track the request generation or database/session identity and ignore responses that no longer match the current state. [stale reference]
Severity Level: Major ⚠️
- ❌ Database switching can display the wrong schema.
- ⚠️ Sidebar schema data may describe the previous database.
- ⚠️ Logout can be followed by stale schema state restoration.(Use Cmd/Ctrl + Click for best experience)
Prompt for AI Agent 🤖
This is a comment left during a code review.
**Path:** frontend/src/lib/appState.svelte.ts
**Line:** 181:181
**Comment:**
*Stale Reference: Starting the schema request without awaiting or associating it with the current database allows its response to update `realSchema` after the user switches databases or logs out. `fetchSchemaAsync()` assigns the response unconditionally, so an older request can overwrite the newly selected database's schema or repopulate schema after logout. Track the request generation or database/session identity and ignore responses that no longer match the current state.
Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix
User description
Last of the fixes from the slow-account-creation investigation. This is the one that multiplied the backend latency into the delay users actually felt.
Problem
appState.init()ran four requests strictly one after another, each waiting on the full round trip of the one before:Only two of those links are real dependencies. From the nginx access log after a signup, the calls landed 3, 6, and 7 seconds apart:
Whatever the per-request backend cost is, this chain paid it four times in series.
Fix 1 — the two workspace calls are independent
/api/workspaces/invites/medepends only onget_current_user:It needs nothing from the workspace list. The old code even issued it before
activeWorkspacewas assigned, so it could never have been using it.Promise.allnow runs both together — one round trip saved on every app load, not just after signup.Fix 2 — don't block navigation on the schema
/api/schemais no longer awaited before navigating. It only feeds the chat UI, which already handles its absence:realSchema = $state<SchemaTable[] | null>(null)— initialised nullAppShell.sveltedefaults the prop:realSchema = nullSo the next screen renders fine without it and fills in when it arrives. Awaiting it held up both
isLoadedand the redirect, leaving the user on a loading screen waiting for data that screen did not need in order to appear.It now loads in the background via the existing
fetchSchemaAsync()helper rather than a second copy of that logic.Result
The serial chain drops from four round trips to two, and the second no longer blocks the redirect.
Verification — and its limits
svelte-check --threshold error: 0 errorsnpm run build, adapter-static): succeedsI want to be straight about what I did not do: I could not capture an authenticated browser trace showing the two requests overlapping, because
init()bails at/api/auth/me401 before reaching them and I did not want to create an account to get past that. There is also no frontend test runner inpackage.jsonto assert the call ordering. So the concurrency claim rests on the code and the dependency analysis, not on a measured before/after like the backend PRs in this series. Worth a reviewer's eye on that specific point.🤖 Generated with Claude Code
CodeAnt-AI Description
Speed up app startup by parallelizing workspace loading and background-loading chat schema data
What Changed
Impact
✅ Faster sign-in and app startup✅ Shorter loading screens before navigation✅ Chat remains available while schema data loads💡 Usage Guide
Checking Your Pull Request
Every time you make a pull request, our system automatically looks through it. We check for security issues, mistakes in how you're setting up your infrastructure, and common code problems. We do this to make sure your changes are solid and won't cause any trouble later.
Talking to CodeAnt AI
Got a question or need a hand with something in your pull request? You can easily get in touch with CodeAnt AI right here. Just type the following in a comment on your pull request, and replace "Your question here" with whatever you want to ask:
This lets you have a chat with CodeAnt AI about your pull request, making it easier to understand and improve your code.
Example
Preserve Org Learnings with CodeAnt
You can record team preferences so CodeAnt AI applies them in future reviews. Reply directly to the specific CodeAnt AI suggestion (in the same thread) and replace "Your feedback here" with your input:
This helps CodeAnt AI learn and adapt to your team's coding style and standards.
Example
Retrigger review
Ask CodeAnt AI to review the PR again, by typing:
Check Your Repository Health
To analyze the health of your code repository, visit our dashboard at https://app.codeant.ai. This tool helps you identify potential issues and areas for improvement in your codebase, ensuring your repository maintains high standards of code health.