Skip to content

perf(workspace): stop the sidebar fetching palette data on every route - #6670

Merged
waleedlatif1 merged 4 commits into
stagingfrom
perf/sidebar-search-lazy
Aug 13, 2026
Merged

perf(workspace): stop the sidebar fetching palette data on every route#6670
waleedlatif1 merged 4 commits into
stagingfrom
perf/sidebar-search-lazy

Conversation

@waleedlatif1

Copy link
Copy Markdown
Collaborator

Summary

The workspace sidebar renders on every route, so anything it fetches is paid on every cold load. Three of its queries — tables, knowledge bases, and the workspace file list — plus the two folder maps that resolve their paths, exist only to populate the Cmd+K palette. The workflow folder map is the one that feeds rendered chrome, and it stays eager.

Those five now wait for the palette to open. The hooks already accept an enabled option for exactly this — useTablesList's own doc says "defer the fetch (e.g. until a menu that needs the list is open)" — and the folder maps follow the disable-by-undefined idiom already used a few lines above for the hidden-tab case. React Query keeps what it fetched, so reopening the palette is served from cache.

SettingsLoader is removed. It eagerly warmed general settings on every workspace route, but the only consumer is the settings surface, which already prefetches the same key server-side, and its sibling sidebar renders only when isOnSettingsPage.

The file list moved to the pages that render it. It lived in the workspace layout because the sidebar registered the query first, and HydrationBoundary defers a query the cache has already seen to a useEffect that SSR never runs — so only the first boundary could reach the server render. With the sidebar deferred, /files and /home can seed it themselves, and /w, /logs, /settings, /tables, and /knowledge stop paying two to three reads and up to ~150 KB for a list they never show. The payload budget moves with it and now only has to protect the pages that do render it.

Net on a cold workspace route that is not Files: six fewer client requests and a smaller document.

Type of Change

  • Performance improvement

Testing

Type-check, lint, and the React Query, client-boundary, and module-graph audits pass. 1,512 tests pass; the same suite on the unmodified base passes 1,510, and no test fails either way.

seedWorkspaceFiles moved to its own module with its tests; the layout prefetch suite now asserts it does not seed the file list, and the Files prefetch suite asserts it does.

Checklist

  • Code follows project style guidelines
  • Self-reviewed my changes
  • Tests added/updated and passing
  • No new warnings introduced
  • I confirm that I have read and agree to the terms outlined in the Contributor License Agreement (CLA)

@vercel

vercel Bot commented Aug 13, 2026

Copy link
Copy Markdown

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

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
docs Skipped Skipped Aug 13, 2026 8:34pm

Request Review

@cursor

cursor Bot commented Aug 13, 2026

Copy link
Copy Markdown

PR Summary

Medium Risk
Changes cold-load query timing and React Query cache keys across many workspace routes; incorrect hydration or permission gating in the palette could cause missing files in search or extra client waterfalls, but there is no direct auth or data-mutation risk.

Overview
Cmd+K palette data is no longer loaded from the persistent sidebar. Tables, knowledge bases, workspace files, and the table/KB folder maps are queried inside SearchModal only while the palette is open (enabled / undefined workspace id), with permission-tab hides applied in memos so cached data cannot leak into hidden sections.

Workspace file list SSR seeding moves off the layout sidebar prefetch into seedWorkspaceFiles (300-file budget, seed nothing on overflow or failed reads). Home and chat pages add HydrationBoundary + prefetchHomeSurface; Files prefetch calls the same seed. Routes like workflow editor, logs, and settings no longer pay for that list or register its query key on every load—so those pages can hydrate a seeded list when they actually need it.

Tests split file-seed behavior into seed-workspace-files.test.ts and flip layout/sidebar expectations (no file list read on sidebar prefetch; Files prefetch seeds it).

Reviewed by Cursor Bugbot for commit c43c934. Configure here.

@greptile-apps

greptile-apps Bot commented Aug 13, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

The PR moves palette-only queries out of the persistent workspace sidebar and relocates workspace-file hydration to the pages that consume it.

  • Tables, files, knowledge bases, and their folder maps now load when the command palette opens.
  • Home, chat, and Files surfaces seed their own workspace-file data through page-level hydration boundaries.
  • The workspace layout no longer reads and serializes the file list for unrelated routes.
  • File-list seeding is extracted into a bounded, failure-tolerant helper with focused tests.

Confidence Score: 5/5

The PR appears safe to merge.

No blocking failure remains.

Important Files Changed

Filename Overview
apps/sim/app/workspace/[workspaceId]/w/components/sidebar/components/search-modal/search-modal.tsx Moves palette-specific resource queries and mapping into the modal while preserving hidden-tab filtering.
apps/sim/app/workspace/[workspaceId]/w/components/sidebar/sidebar.tsx Removes eager palette-only list and folder-map subscriptions from the persistent sidebar.
apps/sim/app/workspace/[workspaceId]/lib/seed-workspace-files.ts Extracts bounded file-list seeding and deliberately falls back to client fetching after oversized or failed reads.
apps/sim/app/workspace/[workspaceId]/home/prefetch.ts Adds authorization-gated file-list seeding for Home surfaces.
apps/sim/app/workspace/[workspaceId]/files/prefetch.ts Moves file-list seeding into the Files surface’s existing authorization-gated prefetch.
apps/sim/app/workspace/[workspaceId]/home/page.tsx Adds page-owned Home prefetching and hydration.
apps/sim/app/workspace/[workspaceId]/chat/[chatId]/page.tsx Adds feature-flag gating and page-owned Home-surface prefetching for chat routes.
apps/sim/app/workspace/[workspaceId]/prefetch.ts Stops the shared workspace layout prefetch from reading and serializing workspace files.

Sequence Diagram

sequenceDiagram
  participant User
  participant Sidebar
  participant Palette as Cmd+K Palette
  participant QueryCache as React Query Cache
  participant API

  Sidebar->>Sidebar: Render on workspace route
  Note over Sidebar,API: Palette-only lists remain deferred
  User->>Palette: Open Cmd+K
  Palette->>QueryCache: Request tables, files, knowledge bases, folder maps
  alt Data is cached and fresh
    QueryCache-->>Palette: Return cached lists
  else Data is absent or stale
    QueryCache->>API: Fetch palette data
    API-->>QueryCache: Return lists and folder maps
    QueryCache-->>Palette: Render searchable entities
  end
Loading

Reviews (6): Last reviewed commit: "fix(chat): guard the chat page prefetch ..." | Re-trigger Greptile

Comment thread apps/sim/app/workspace/[workspaceId]/home/page.tsx
Comment thread apps/sim/app/workspace/[workspaceId]/home/page.tsx Outdated
@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@greptile

@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@cursor review

Comment thread apps/sim/app/workspace/[workspaceId]/layout.tsx
@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

Researched the registration problem properly and found the clean fix — it needed no mounting changes at all.

SearchModal is already a thin shell:

export function SearchModal({ open, ...props }: SearchModalProps) {
  const [mounted, setMounted] = useState(false)
  useEffect(() => { setMounted(true) }, [])
  if (!mounted || !open) return null
  return <SearchModalContent {...props} />
}

SearchModalContent only exists while the palette is open, and it already derives workspaceId from useParams() and reads usePermissionConfig(). So the five queries and their three memos moved there and needed no new props — the component that uses the data now owns fetching it.

That is strictly better than the enabled: false gating it replaces. Verified in the query-core source why: useBaseQuery builds its observer in a useState initializer unconditionally, the constructor calls #updateQuery()queryCache.build()add(), with no enabled check on that path. A disabled query does not fetch, but it still registers — which both leaves the key in the cache on routes that never show it and blocks a page from seeding that key during the server render, since HydrationBoundary defers an already-registered query to an effect SSR never runs.

Now nothing registers those keys unless the palette is open. Also removed four imports the move orphaned in sidebar.tsx, and updated the search-modal test to drive the Tables section through the mocked hook rather than the removed prop.

Deliberately not in this PR: moving the file-list seed out of the layout onto /files, /home, and /chat. That is now unblocked and is the remaining waste — the layout still seeds a list that only those three routes render. I want this premise confirmed in CI and staging first, since my previous attempt at the seed move rested on an assumption about enabled that turned out to be wrong.

@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@greptile

@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@cursor review

@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@greptile

@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@cursor review

Comment thread apps/sim/app/workspace/[workspaceId]/prefetch.ts Outdated
@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@greptile

@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@cursor review

Comment thread apps/sim/app/workspace/[workspaceId]/chat/[chatId]/page.tsx
@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@greptile

@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@cursor review

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Bugbot reviewed your changes and found no new issues!

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit c43c934. Configure here.

@waleedlatif1
waleedlatif1 merged commit 0758df3 into staging Aug 13, 2026
24 checks passed
@waleedlatif1
waleedlatif1 deleted the perf/sidebar-search-lazy branch August 13, 2026 20:41
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