perf(platform): make warm dashboard page transitions near-instant#1833
Conversation
Page-to-page navigation flashed a skeleton on every transition. The loaders meant to warm list data didn't: Convex's usePaginatedQuery keys its first page with a fresh per-mount id, so a convexQuery loader prefetch never matches the subscription the table reads — and the _knowledge routes prefetched the non-paginated listX the tables never read (a full-collection scan per nav and per intent-hover). - Add primeCachedPaginatedQuery: a loader does a one-shot page-0 query and writes it into the same module cache useCachedPaginatedQuery reads on remount. Wired into customers/products/vendors/websites/documents/ conversations loaders, replacing the broken prefetches. - Prefetch the non-paginated reads that warm correctly (projects list, documents count + folders, getMyTeams in the shell loader). - Prefetch action-backed lists/detail (agents, automations) via shared query-key factories so loader and hook can't drift. - Wire the existing-but-unused row-hover preload (onRowMouseEnter + usePreloadRoute) on projects/agents tables, with detail-route loaders; documents rows hover-prefetch the cheap getDocumentById point query. - Set a global staleTime + refetchOnWindowFocus:false; Convex keeps subscribed data live over the WS, so this only drops redundant one-shot refetches on mount/focus.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro Run ID: 📒 Files selected for processing (22)
📝 WalkthroughWalkthroughThis PR introduces systematic data warming across the dashboard to reduce perceived load times. It establishes shared infrastructure ( Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Warning Billing warning: we have not been able to collect payment for this subscription for more than 72 hours. Please update the payment method or pay any pending invoices in Billing to avoid service interruption. 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 |
Why
Navigating between dashboard pages flashed a skeleton on nearly every transition. The route loaders that were meant to warm list data didn't work: Convex's
usePaginatedQuerykeys its first page with a fresh per-mountpaginationOpts.id, so aconvexQueryloader prefetch never matches the subscription the table actually reads — andusePaginatedQueryreads the Convex client store, not the react-query cache thatconvexQuerywarms. The four_knowledgeroutes were worse: they prefetched the non-paginatedlistX(a full-collection scan) that the tables never read — firing on every nav and every intent-hover.This makes warm transitions near-instant by warming exactly what each page reads.
What changed
primeCachedPaginatedQuery(app/hooks/use-cached-paginated-query.ts) — a loader does a one-shot page-0 query and writes it into the same module cacheuseCachedPaginatedQueryreads on remount, sidestepping theidmismatch entirely. Wired into the customers / products / vendors / websites / documents / conversations loaders, replacing the broken prefetches. Keyed on each list's base args (in-page filters ride the live subscription).convexQueryprefetch for non-paginated reads that do warm correctly: projects list (matching the table'sincludeArchived: false), documents count + root folders, andgetMyTeamsin the$idshell loader.configKeys, newworkflowListKey) so the loader and hook can't drift.onRowMouseEnter+usePreloadRouteon the projects & agents tables (with detail-route loaders forgetProject/readAgent); documents rows hover-prefetch the cheapgetDocumentByIdpoint query.app/router.tsx):staleTime: 5min+refetchOnWindowFocus: false— safe because Convex keeps subscribed data live over the WS; this only drops redundant one-shot refetches on mount/focus.Deferred (follow-ups, intentionally out of scope)
storage.getUrl()in the list transform (backend change; needs tracing the URL consumers in preview/download).loadMore(200)/pageSize*3client-side eager-load and server-side search (the eager-load is load-bearing for client-side team filtering).Note to reviewers
Sidebar links use
preload="render", so these loaders run on dashboard entry. Net backend work is lower than before (page-0 primes replace full-collection scans), but if aggregate load looks chatty in practice, downgrade the heaviest list links topreload="intent"or raisedefaultPreloadDelay.Verification
bun run check(format, lint, typecheck, all 71,533 server+pii tests) — green.test:ui) pass, incl. a new test forprimeCachedPaginatedQuery; updated two existing tests for the new provider deps (useRouter,useQueryClient).messages/{en,de,fr}.json— N/A (no user-facing strings; comments only)./docs/{en,de,fr}/— N/A (perf-only; no new/changed UI elements or copy).Summary by CodeRabbit
Release Notes
New Features
Performance
Tests