Skip to content

perf(platform): make warm dashboard page transitions near-instant#1833

Merged
yannickmonney merged 1 commit into
mainfrom
perf/warm-page-transitions
Jun 5, 2026
Merged

perf(platform): make warm dashboard page transitions near-instant#1833
yannickmonney merged 1 commit into
mainfrom
perf/warm-page-transitions

Conversation

@yannickmonney

@yannickmonney yannickmonney commented Jun 5, 2026

Copy link
Copy Markdown
Contributor

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 usePaginatedQuery keys its first page with a fresh per-mount paginationOpts.id, so a convexQuery loader prefetch never matches the subscription the table actually reads — and usePaginatedQuery reads the Convex client store, not the react-query cache that convexQuery warms. The four _knowledge routes were worse: they prefetched the non-paginated listX (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 cache useCachedPaginatedQuery reads on remount, sidestepping the id mismatch 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).
  • Effective convexQuery prefetch for non-paginated reads that do warm correctly: projects list (matching the table's includeArchived: false), documents count + root folders, and getMyTeams in the $id shell loader.
  • Action-backed prefetch for agents & automations lists/detail via shared query-key factories (configKeys, new workflowListKey) so the loader and hook can't drift.
  • Row-hover preload — wired the already-present-but-unused onRowMouseEnter + usePreloadRoute on the projects & agents tables (with detail-route loaders for getProject / readAgent); documents rows hover-prefetch the cheap getDocumentById point query.
  • Global query defaults (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)

  • Trimming documents' per-row storage.getUrl() in the list transform (backend change; needs tracing the URL consumers in preview/download).
  • The loadMore(200) / pageSize*3 client-side eager-load and server-side search (the eager-load is load-bearing for client-side team filtering).
  • Paginating the unbounded conversation-detail message load (why conversation rows are not hover-prefetched here — it would amplify that fetch).

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 to preload="intent" or raise defaultPreloadDelay.

Verification

  • Ran bun run check (format, lint, typecheck, all 71,533 server+pii tests) — green.
  • Affected UI tests (test:ui) pass, incl. a new test for primeCachedPaginatedQuery; updated two existing tests for the new provider deps (useRouter, useQueryClient).
  • CodeRabbit review — 0 findings.
  • No hand-rolled skeletons — N/A (this removes skeleton flashes via the existing cache).
  • 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).
  • READMEs — N/A.

Summary by CodeRabbit

Release Notes

  • New Features

    • Table rows now preload data on hover for faster navigation.
    • Routes prefetch page data during navigation to improve loading times.
  • Performance

    • Optimized paginated query caching to reduce initial loading UI.
    • Updated query client configuration for better WebSocket subscription handling.
  • Tests

    • Added test coverage for paginated query caching behavior.

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.
@coderabbitai

coderabbitai Bot commented Jun 5, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 6e1beb99-3a4c-4dea-870b-df20c19dd042

📥 Commits

Reviewing files that changed from the base of the PR and between 788c6c2 and 160bda1.

📒 Files selected for processing (22)
  • services/platform/app/features/agents/components/agents-table.test.tsx
  • services/platform/app/features/agents/components/agents-table.tsx
  • services/platform/app/features/automations/hooks/file-queries.ts
  • services/platform/app/features/documents/components/documents-table.test.tsx
  • services/platform/app/features/documents/components/documents-table.tsx
  • services/platform/app/features/projects/components/projects-table.tsx
  • services/platform/app/hooks/use-cached-paginated-query.test.ts
  • services/platform/app/hooks/use-cached-paginated-query.ts
  • services/platform/app/hooks/use-table-config-factory.ts
  • services/platform/app/router.tsx
  • services/platform/app/routes/dashboard/$id.tsx
  • services/platform/app/routes/dashboard/$id/_knowledge/customers.tsx
  • services/platform/app/routes/dashboard/$id/_knowledge/documents.tsx
  • services/platform/app/routes/dashboard/$id/_knowledge/products.tsx
  • services/platform/app/routes/dashboard/$id/_knowledge/vendors.tsx
  • services/platform/app/routes/dashboard/$id/_knowledge/websites.tsx
  • services/platform/app/routes/dashboard/$id/agents/$agentId.tsx
  • services/platform/app/routes/dashboard/$id/agents/index.tsx
  • services/platform/app/routes/dashboard/$id/automations/index.tsx
  • services/platform/app/routes/dashboard/$id/conversations/$status.tsx
  • services/platform/app/routes/dashboard/$id/projects/$projectId.tsx
  • services/platform/app/routes/dashboard/$id/projects/index.tsx

📝 Walkthrough

Walkthrough

This PR introduces systematic data warming across the dashboard to reduce perceived load times. It establishes shared infrastructure (primeCachedPaginatedQuery, workflowListKey, DEFAULT_TABLE_PAGE_SIZE, and refined React Query defaults), then applies prefetching and route preloading strategies in three areas: table row hover handlers that warm single-item queries or route loaders, and route loaders that prefetch list queries before rendering. Together, these changes reduce skeleton flash and improve the initial paint experience across agents, automations, conversations, documents, customers, products, projects, vendors, and websites views.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • tale-project/tale#1735: Both PRs extend Projects table navigation by adding hover-based route preloading to ProjectsTable.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 44.44% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely summarizes the main change: improving dashboard page transitions by making them near-instant through warming data preload.
Description check ✅ Passed The description comprehensively covers the problem, changes, verification steps, and deferred items, though it lacks explicit tick marks for all pre-merge checklist items.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch perf/warm-page-transitions

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.

❤️ Share

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

@yannickmonney yannickmonney merged commit 626ff12 into main Jun 5, 2026
30 checks passed
@yannickmonney yannickmonney deleted the perf/warm-page-transitions branch June 5, 2026 08:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant