close
Skip to content

improvement(perf): cut server-only and unused code out of the workspace client bundles - #6975

Merged
waleedlatif1 merged 2 commits into
stagingfrom
perf/sidebar-nav-speed
Aug 22, 2026
Merged

improvement(perf): cut server-only and unused code out of the workspace client bundles#6975
waleedlatif1 merged 2 commits into
stagingfrom
perf/sidebar-nav-speed

Conversation

@waleedlatif1

Copy link
Copy Markdown
Collaborator

Summary

Every workspace route was shipping JavaScript it never executes. Four independent import edges, each fixed by moving a symbol — no behaviour changes.

  • js-tiktoken (5.4 MB source / 2.5 MB wire) reached the workflow editor because the tokenization barrel re-exported the exact counters next to the character heuristics. Split into lib/tokenization/accurate.ts; the barrel no longer re-exports them. Only the KB chunk editor, embeddings client, and agent memory handler need exact counts, and all three still get them.
  • crypto-browserify (~105 KB gzip, all 26 workspace routes) came from the Salesforce and Gong triggers importing webhook provider modules that reach node:crypto via @sim/security — server-only signature verification shipping to every browser. The two symbols the triggers actually need (a payload-shape helper and a config key) moved to crypto-free modules.
  • tables, files, knowledge each imported one dependency-free hook (useContextMenu) from the 21-export sidebar-hooks barrel, whose other exports reach the 5 MB generated tool-metadata artifact via stores/workflow-diff → serializer. Deep-imported per the "Code-splitting through barrels" rule in sim-imports.md. The barrel export stays — sidebar internals still use it.
  • lib/workflows/subblocks/display.ts imported a string constant from a React module under app/, inverting the app/lib layering and pulling React + emcn + the block registry along for one string. Moved to lib/workflows/workflow-labels.ts.

Also adds a loading boundary to chat/[chatId]. With cacheComponents off, a <Link> prefetch degrades to Next's LoadingBoundary strategy, which prefetches a dynamic route only as far as its nearest loading segment — so a route without one is prefetched as nothing and the click held the previous chat on screen for the whole server round trip.

Measurements

Production build, JS downloaded before the load event:

route before after
/w/[workflowId] 7.38 MB 4.80 MB (−35%)
/logs 4.57 MB 4.44 MB
/knowledge 4.35 MB 4.22 MB
/home 4.57 MB 4.44 MB

crypto-browserify no longer appears in any shipped chunk. The tool-registry boundary baseline is retightened so the reclaimed graph weight can't silently regress.

Worth setting expectations on the last three rows: the barrel fix removes ~5.3 MB of source from those route graphs but only ~130 KB of wire bytes, because the persistent sidebar and socket provider in the workspace layout reach the same modules through hooks/queries/deployments → workflows/comparison/compare → hooks/selectors/registry. Until that shell edge is addressed, per-route graph fixes can't pay out fully. Noted below.

Not in this PR

Investigated and deliberately left out:

  • A generated block-metadata artifact. Not feasible as a drop-in: block configs carry 1,345 value: () => … closures across 271 files, tools.config.tool in 268 files, and icon fields that are React components. serializer and visibility legitimately need the closures.
  • staleTimes.dynamic. Refuted — it's live at exactly one call site reachable only through the BFCache path; the segment cache under STATIC_STALETIME_MS is what already serves these navigations. It would buy nothing and accept stale session-dependent output.
  • A loading.tsx for w/[workflowId]. Written, then dropped: it reproducibly caused a React chore(deps): bump the workspace-dependencies group with 22 updates #418 hydration mismatch on that route. Confirmed by A/B — clean build without the file, error with it. The editor's loading boundary needs to match its SSR output, which is its own piece of work.

Type of Change

  • Performance improvement

Testing

Tested manually against a production build. 1,264 tests pass across the touched areas (tokenization, embeddings, agent memory, webhook providers, salesforce/gong triggers, workflow subblocks, logs). bun run type-check clean, bun run lint clean, all 32 audits in check:audits pass, block-registry audit passes. All eight workspace routes verified rendering with zero console errors in a headless browser.

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)

…ce client bundles

Every workspace route shipped JavaScript it never executes. Four independent
import edges, each fixed by moving a symbol rather than changing behaviour:

- js-tiktoken's BPE rank tables (5.4 MB source / 2.5 MB wire) reached the
  workflow editor because the tokenization barrel re-exported the exact
  counters alongside the character heuristics. Split into
  lib/tokenization/accurate.ts, which the barrel no longer re-exports.
- crypto-browserify (~105 KB gzip, all 26 workspace routes) came from the
  Salesforce and Gong triggers importing webhook provider modules that reach
  node:crypto through @sim/security. The two symbols they actually needed are
  now in crypto-free modules.
- tables, files and knowledge each imported one dependency-free hook from the
  sidebar-hooks barrel, whose other exports reach the 5 MB generated
  tool-metadata artifact. Deep-imported per the code-splitting rule in
  sim-imports.md.
- lib/workflows/subblocks/display.ts imported a string constant from a React
  module under app/, inverting the app/lib layering. Moved to lib/.

Also adds a loading boundary to chat/[chatId]. Without one, a dynamic route is
prefetched as nothing, so clicking a chat held the previous chat on screen for
the whole server round trip.

Measured on a production build, JS downloaded before the load event:

  /w/[workflowId]  7.38 MB -> 4.80 MB  (-35%)
  /logs            4.57 MB -> 4.44 MB
  /knowledge       4.35 MB -> 4.22 MB
  /home            4.57 MB -> 4.44 MB

crypto-browserify no longer appears in any shipped chunk. The tool-registry
boundary baseline is retightened so the reclaimed graph weight cannot silently
regress.
@vercel

vercel Bot commented Aug 22, 2026

Copy link
Copy Markdown

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

Project Deployment Actions Updated (UTC)
Image docs Ready Ready Preview Aug 22, 2026 4:09am

Request Review

@cursor

cursor Bot commented Aug 22, 2026

Copy link
Copy Markdown

PR Summary

Medium Risk
Import-graph surgery across tokenization, webhooks, and many workspace routes; behavior is meant to stay the same, but a missed import could reintroduce a huge client chunk or break exact token counting / trigger config.

Overview
Cuts unused JavaScript from workspace routes by breaking four import edges. No intended behavior change except chat navigation.

Exact tiktoken counting moves from estimators.ts into lib/tokenization/accurate.ts and is no longer re-exported from the tokenization barrel, so the workflow editor no longer pulls js-tiktoken (~2.5 MB on the wire). Embeddings, agent memory, and the KB chunk editor still import the accurate module directly.

Gong/Salesforce triggers now import crypto-free helpers (gong-config, salesforce-payload) instead of the full webhook provider modules, so node:crypto / crypto-browserify no longer ships to the browser.

useContextMenu is imported from @/hooks/use-context-menu instead of the sidebar-hooks barrel, so files/knowledge/tables (and other list surfaces) no longer pull the workflow-diff/tool-metadata graph. DELETED_WORKFLOW_LABEL moves to lib/workflows/workflow-labels.ts so lib no longer imports a React logs util for one string.

Adds chat/[chatId]/loading.tsx so Link prefetch can commit immediately when cacheComponents is off. Tool-registry boundary baseline is retightened to match the smaller graphs.

Reviewed by Cursor Bugbot for commit 2487a0f. Configure here.

@greptile-apps

greptile-apps Bot commented Aug 22, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

The PR reduces workspace client bundles by separating server-only and heavyweight dependencies from browser-facing import graphs, relocating a generic context-menu hook into the shared hooks directory, and adding a chat loading boundary.

  • Moves exact tokenization helpers into a dedicated module while retaining them for the consumers that need accurate counts.
  • Extracts crypto-free Salesforce and Gong trigger helpers from server-side webhook-provider modules.
  • Moves the generic context-menu hook from the workflow sidebar into shared hooks and updates all consumers.
  • Moves the deleted-workflow label into the workflow library layer and retightens the tool-registry boundary baseline.
  • Adds a route-level loading boundary for chat navigation.

Confidence Score: 5/5

The PR appears safe to merge.

No blocking failure remains; the previously reported import-boundary issue was resolved by moving the generic hook unchanged into shared hooks, updating all consumers, and removing the competing sidebar export.

Important Files Changed

Filename Overview
apps/sim/hooks/use-context-menu.ts Relocates the generic hook without implementation changes; consumers consistently use the new shared path.
apps/sim/app/workspace/[workspaceId]/w/components/sidebar/hooks/index.ts Removes the obsolete context-menu re-export after all affected consumers were migrated.
apps/sim/lib/tokenization/accurate.ts Isolates heavyweight exact-tokenization helpers from the lightweight tokenization barrel.
apps/sim/lib/webhooks/providers/salesforce-payload.ts Extracts payload-shape logic so client-side trigger code no longer imports the server webhook-provider graph.
apps/sim/lib/webhooks/providers/gong-config.ts Extracts Gong configuration metadata into a crypto-free module for client consumers.
apps/sim/app/workspace/[workspaceId]/chat/[chatId]/loading.tsx Adds a route loading boundary using the existing home fallback surface.

Reviews (2): Last reviewed commit: "improvement(sidebar): move useContextMen..." | Re-trigger Greptile

Comment thread apps/sim/app/workspace/[workspaceId]/files/files.tsx Outdated
Review flagged the four workspace routes deep-importing `useContextMenu` from
the sidebar's hooks barrel as a barrel-convention violation. Fair — the
code-splitting exception in sim-imports.md is written for `lazy()` splits, and
these are static imports.

The hook was in the wrong place to begin with. It is entirely generic — no
sidebar-specific references, just right-click state and positioning — and nine
consumers across tables, files, knowledge, home, the terminal and the preview
editor already reached across features to get it. Moved to `@/hooks`, the
repo's shared-hooks location, and every consumer including the sidebar's own
now imports it from there.

This satisfies the barrel convention rather than making an exception to it, and
keeps the graph win: tables, knowledge and files stay off the sidebar barrel's
path to `stores/workflow-diff -> serializer -> tools/metadata`, unchanged at
20.19 / 20.89 / 21.37 MB of reachable source.
@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 2487a0f. Configure here.

@waleedlatif1
waleedlatif1 merged commit d1b0184 into staging Aug 22, 2026
30 checks passed
@waleedlatif1
waleedlatif1 deleted the perf/sidebar-nav-speed branch August 22, 2026 04:14
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