You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
perf(dashboard): migrate to useAsyncData with SSR hydration and seed (#169)
### 🔗 Linked issue
<!-- No open issue — performance improvement initiative from internal
profiling -->
### 🧭 Context
Loading `/guilds/:id/manage` was slower than needed because the
dashboard layout fetched all guild data on the client (`onMounted`),
blocking the first render and causing a visible loading flash on every
page navigation. This PR migrates the dashboard layout to SSR-aware data
fetching via `useAsyncData` and ships the test infrastructure to
validate async data and concurrency patterns.
The previous commits on this branch delivered the server-side half of
this work:
- N+1 Discord API fan-out eliminated with `mapWithConcurrency(limit=8)`
and `includeChannels: false` for non-channel contexts
- Sequential `getCurrentUser` fan-out replaced with `Promise.all`
- Duplicate `readSettings` DB call eliminated across guild handlers
- Uncached `api.guilds.getChannels` replaced with a cached helper
- `Cache-Control: private, max-age=30, stale-while-revalidate=300` added
to `/api/users`
This commit delivers the client/SSR half.
### 📚 Description
**`app/layouts/dashboard.vue`**
- Replaced the `onMounted` dual-fetch pattern with `useAsyncData` so the
server renders the sidebar on first load instead of showing a skeleton
- Key is a reactive factory `() => \`dashboard:guild:${guildId.value}\``
so switching guilds triggers an automatic refetch without a full
navigation
- Added `useRequestFetch()` to forward auth cookies when the handler
runs on the server (required for `nuxt-auth-utils` session resolution in
SSR)
- Sidebar is seeded from `userGuilds.value?.find(g => g.id ===
guildId.value)` before the async data resolves, preventing a layout
shift where the guild name flickers
- `pending` replaces the manual `isLoading` ref; error watch
(`401`/`403`/default) is preserved unchanged
**Test infrastructure (`test/`)**
- `test/mocks/discord.ts` — Added typed mock factories: `mockGetGuild`,
`mockGetGuildChannels`, `mockGetMember`, `mockReadSettings`, using
`APIGuild`, `APIGuildMember`, `APIChannel` from `discord-api-types/v10`
- `test/fixtures/oauth-guilds.ts` — `FIXTURE_OAUTH_GUILDS`: 50-entry
`RESTAPIPartialCurrentUserGuild[]` array for use in concurrency and
pagination tests
- `test/nuxt/dashboard-layout.spec.ts` — Extended with async data
watcher tests covering guild-switch refetch, SSR hydration path, and
error handling branches
All 424 unit tests pass.
0 commit comments