Skip to content

Commit d1b0a62

Browse files
committed
improvement(perf): cut server-only and unused code out of the workspace 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.
1 parent 8937bb3 commit d1b0a62

28 files changed

Lines changed: 447 additions & 357 deletions

File tree

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import { HomeFallback } from '@/app/workspace/[workspaceId]/home/home-fallback'
2+
3+
/**
4+
* Route-level loading boundary for a chat.
5+
*
6+
* Its real job is prefetching, not painting. With `cacheComponents` off, a
7+
* default `<Link>` prefetch degrades to Next's LoadingBoundary strategy, which
8+
* prefetches a dynamic route only as far as its nearest `loading` segment — so
9+
* a route without one is prefetched as nothing, and clicking a chat leaves the
10+
* previous chat frozen on screen until the server responds. This file is what
11+
* makes that click commit immediately.
12+
*
13+
* Renders the same surface `HomeFallback` gives the Suspense boundary inside
14+
* the page, so the loading frame and the mounted frame share a background and
15+
* the transition reads as one step rather than two.
16+
*/
17+
export default function ChatLoading() {
18+
return <HomeFallback />
19+
}

apps/sim/app/workspace/[workspaceId]/files/files.tsx

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,13 @@ import {
128128
} from '@/app/workspace/[workspaceId]/files/untitled-title'
129129
import { useRegisterGlobalCommands } from '@/app/workspace/[workspaceId]/providers/global-commands-provider'
130130
import { useUserPermissionsContext } from '@/app/workspace/[workspaceId]/providers/workspace-permissions-provider'
131-
import { useContextMenu } from '@/app/workspace/[workspaceId]/w/components/sidebar/hooks'
131+
/**
132+
* Deep-imported rather than taken from the `sidebar/hooks` barrel on purpose. That barrel
133+
* also exports `useWorkflowOperations`, whose graph reaches `stores/workflow-diff` ->
134+
* `serializer` -> `tools/metadata`, pulling the 5 MB generated tool-metadata artifact into
135+
* this route's client bundle for a hook that is a dependency-free leaf.
136+
*/
137+
import { useContextMenu } from '@/app/workspace/[workspaceId]/w/components/sidebar/hooks/use-context-menu'
132138
import { usePinItem, usePinnedIds, useUnpinItem } from '@/hooks/queries/pinned-items'
133139
import { useWorkspaceMembersQuery, type WorkspaceMember } from '@/hooks/queries/workspace'
134140
import {

apps/sim/app/workspace/[workspaceId]/knowledge/[id]/[documentId]/components/chunk-editor/chunk-editor.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import { isApiClientError } from '@/lib/api/client/errors'
66
import { requestJson } from '@/lib/api/client/request'
77
import { getKnowledgeChunkContract } from '@/lib/api/contracts/knowledge'
88
import type { ChunkData, DocumentData } from '@/lib/knowledge/types'
9-
import { getAccurateTokenCount, getTokenStrings } from '@/lib/tokenization/estimators'
9+
import { getAccurateTokenCount, getTokenStrings } from '@/lib/tokenization/accurate'
1010
import { useCreateChunk, useUpdateChunk } from '@/hooks/queries/kb/knowledge'
1111
import { useAutosave } from '@/hooks/use-autosave'
1212

apps/sim/app/workspace/[workspaceId]/knowledge/knowledge.tsx

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,13 @@ import {
7979
} from '@/app/workspace/[workspaceId]/knowledge/search-params'
8080
import { useRegisterGlobalCommands } from '@/app/workspace/[workspaceId]/providers/global-commands-provider'
8181
import { useUserPermissionsContext } from '@/app/workspace/[workspaceId]/providers/workspace-permissions-provider'
82-
import { useContextMenu } from '@/app/workspace/[workspaceId]/w/components/sidebar/hooks'
82+
/**
83+
* Deep-imported rather than taken from the `sidebar/hooks` barrel on purpose. That barrel
84+
* also exports `useWorkflowOperations`, whose graph reaches `stores/workflow-diff` ->
85+
* `serializer` -> `tools/metadata`, pulling the 5 MB generated tool-metadata artifact into
86+
* this route's client bundle for a hook that is a dependency-free leaf.
87+
*/
88+
import { useContextMenu } from '@/app/workspace/[workspaceId]/w/components/sidebar/hooks/use-context-menu'
8389
import { BrandIcon } from '@/blocks/brand-icon'
8490
import { CONNECTOR_META_REGISTRY } from '@/connectors/registry'
8591
import { useKnowledgeBasesList } from '@/hooks/kb/use-knowledge'

apps/sim/app/workspace/[workspaceId]/logs/components/dashboard/components/workflows-list/workflows-list.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import { memo } from 'react'
22
import { cn, handleKeyboardActivation } from '@sim/emcn'
33
import { Workflow } from '@sim/emcn/icons'
4+
import { DELETED_WORKFLOW_LABEL } from '@/lib/workflows/workflow-labels'
45
import { FloatingOverflowText } from '@/app/workspace/[workspaceId]/components'
5-
import { DELETED_WORKFLOW_LABEL } from '@/app/workspace/[workspaceId]/logs/utils'
66
import { StatusBar, type StatusBarSegment } from '..'
77

88
export interface WorkflowExecutionItem {

apps/sim/app/workspace/[workspaceId]/logs/components/log-details/log-details.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ import { MothershipHandoffStorage } from '@/lib/core/utils/browser-storage'
4747
import { filterHiddenOutputKeys } from '@/lib/logs/execution/trace-spans/trace-spans'
4848
import type { TraceSpan } from '@/lib/logs/types'
4949
import { sendMothershipMessage } from '@/lib/mothership/events'
50+
import { DELETED_WORKFLOW_LABEL } from '@/lib/workflows/workflow-labels'
5051
import {
5152
ExecutionSnapshot,
5253
FileCards,
@@ -58,7 +59,6 @@ import {
5859
logDetailsTabUrlKeys,
5960
} from '@/app/workspace/[workspaceId]/logs/search-params'
6061
import {
61-
DELETED_WORKFLOW_LABEL,
6262
formatDate,
6363
getDisplayStatus,
6464
resolveLogWorkflowId,

apps/sim/app/workspace/[workspaceId]/logs/logs.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ import {
4949
type WorkflowData,
5050
} from '@/lib/logs/search-suggestions'
5151
import { SEARCH_DEBOUNCE_MS } from '@/lib/url-state'
52+
import { DELETED_WORKFLOW_LABEL } from '@/lib/workflows/workflow-labels'
5253
import type {
5354
FilterTag,
5455
ResourceAction,
@@ -94,7 +95,6 @@ import { useFilterStore } from '@/stores/logs/filters/store'
9495
import { CORE_TRIGGER_TYPES } from '@/stores/logs/filters/types'
9596
import { Dashboard, ExecutionSnapshot, LogDetails, LogRowContextMenu } from './components'
9697
import {
97-
DELETED_WORKFLOW_LABEL,
9898
formatDate,
9999
getDisplayStatus,
100100
type LogStatus,

apps/sim/app/workspace/[workspaceId]/logs/utils.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,6 @@ export const LOG_COLUMNS = {
1515
duration: { width: 'w-[20%]', minWidth: 'min-w-[100px]', label: 'Duration' },
1616
} as const
1717

18-
export const DELETED_WORKFLOW_LABEL = 'Deleted Workflow'
19-
2018
/**
2119
* Resolves the workflow a log row points at, or null when there is nowhere to
2220
* navigate. Sim agent jobs have no workflow of their own, and a deleted

apps/sim/app/workspace/[workspaceId]/settings/secrets/[credentialId]/components/secret-usage-panel/secret-usage-panel.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,9 @@ import { ChipLink } from '@sim/emcn'
55
import { formatDateTime } from '@sim/utils/formatting'
66
import { SettingsActionChip } from '@/components/settings/settings-header'
77
import type { SecretUsageEntryPayload, SecretUsageScope } from '@/lib/api/contracts'
8+
import { DELETED_WORKFLOW_LABEL } from '@/lib/workflows/workflow-labels'
89
import { FloatingOverflowText } from '@/app/workspace/[workspaceId]/components'
9-
import { DELETED_WORKFLOW_LABEL, TriggerBadge } from '@/app/workspace/[workspaceId]/logs/utils'
10+
import { TriggerBadge } from '@/app/workspace/[workspaceId]/logs/utils'
1011
import {
1112
ActivityLog,
1213
type ActivityLogEntry,

apps/sim/app/workspace/[workspaceId]/tables/tables.tsx

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,13 @@ import {
7777
tablesSortParams,
7878
tablesUrlKeys,
7979
} from '@/app/workspace/[workspaceId]/tables/search-params'
80-
import { useContextMenu } from '@/app/workspace/[workspaceId]/w/components/sidebar/hooks'
80+
/**
81+
* Deep-imported rather than taken from the `sidebar/hooks` barrel on purpose. That barrel
82+
* also exports `useWorkflowOperations`, whose graph reaches `stores/workflow-diff` ->
83+
* `serializer` -> `tools/metadata`, pulling the 5 MB generated tool-metadata artifact into
84+
* this route's client bundle for a hook that is a dependency-free leaf.
85+
*/
86+
import { useContextMenu } from '@/app/workspace/[workspaceId]/w/components/sidebar/hooks/use-context-menu'
8187
import { useCreateFolder, useDeleteFolderMutation, useUpdateFolder } from '@/hooks/queries/folders'
8288
import { usePinItem, usePinnedIds, useUnpinItem } from '@/hooks/queries/pinned-items'
8389
import {

0 commit comments

Comments
 (0)