perf(renderer): load the project-location and feedback dialogs on click

Both are reachable only from an explicit click, but their chunks sat on the
renderer boot graph and were fetched and parsed on every launch. Route them
through the existing `lazy-with-retry` helper, keeping each trigger eager so the
click target still exists, and keep the mount sticky once opened so the dialog's
own close animation and repeat opens are unaffected.

Renderer boot graph 4,473,242 -> 4,424,142 bytes (-49,100 B / -47.9 KiB).

Trade-off: the first open per session now waits on a local chunk fetch —
measured at ~0.53 ms (project location) and ~0.26 ms (feedback) of read plus V8
parse/compile, warm page cache.
This commit is contained in:
Neil
2026-09-03 20:42:30 -07:00
parent 7ed86a98ae
commit a5e806031c
3 changed files with 53 additions and 12 deletions
@@ -225,7 +225,8 @@ describe('NewWorkspaceComposerCard set location', () => {
container = null
})
it('opens set-location over the composer without leaving the create dialog', () => {
// Async because the dialog is a lazy chunk: the click mounts Suspense, the chunk resolves next tick.
it('opens set-location over the composer without leaving the create dialog', async () => {
const nestedOpenChanges: boolean[] = []
container = renderCard({
onNestedDialogOpenChange: (open) => nestedOpenChanges.push(open)
@@ -239,6 +240,7 @@ describe('NewWorkspaceComposerCard set location', () => {
)
expect(setLocation).toBeTruthy()
act(() => setLocation?.click())
await act(async () => {})
const dialog = document.body.querySelector('[data-testid="set-project-location-dialog"]')
expect(dialog?.getAttribute('data-host')).toBe('Devbox')
@@ -11,7 +11,7 @@ import {
AddRemoteHostDialog,
type AddRemoteHostMode
} from '@/components/sidebar/AddRemoteHostDialog'
import { SetProjectLocationDialog } from '@/components/new-workspace/SetProjectLocationDialog'
import { lazyWithRetry } from '@/lib/lazy-with-retry'
import { unwrapRuntimeRpcResult } from '@/runtime/runtime-rpc-client'
import { withUiConnectTimeout } from '@/ssh/ssh-connect-ui-timeout'
import { isSshConnectInFlight, trackSshConnect } from '@/ssh/ssh-connect-in-flight'
@@ -37,6 +37,16 @@ import {
import { getSshStatusLabel } from './new-workspace/new-workspace-composer-ssh-status'
import { useComposerFileDragOver } from './new-workspace/use-composer-file-drag-over'
// Why lazy: this pulls the ~41 KB project-location browser onto the boot graph, and nothing
// reaches it without an explicit "Set location" click.
const SetProjectLocationDialog = lazyWithRetry(
() =>
import('@/components/new-workspace/SetProjectLocationDialog').then((module) => ({
default: module.SetProjectLocationDialog
})),
{ reloadKey: 'set-project-location-dialog' }
)
export default function NewWorkspaceComposerCard(
props: NewWorkspaceComposerCardProps
): React.JSX.Element {
@@ -83,6 +93,12 @@ export default function NewWorkspaceComposerCard(
const [setLocationOption, setSetLocationOption] = React.useState<NeedsProjectHostOption | null>(
null
)
// Why sticky: the dialog animates itself closed off its own `option` prop, so unmounting it
// when the option clears would cut that animation short.
const setLocationDialogRequested = React.useRef(false)
if (setLocationOption !== null) {
setLocationDialogRequested.current = true
}
const selectedRepo = eligibleRepos.find((candidate) => candidate.id === repoId)
const selectedRepoName = selectedRepo?.displayName ?? selectedRepo?.path ?? 'This project'
@@ -319,14 +335,18 @@ export default function NewWorkspaceComposerCard(
submitShortcutModifierLabel={getScreenSubmitModifierLabel()}
/>
<AddRemoteHostDialog mode={addRemoteHostMode} onOpenChange={setAddRemoteHostMode} />
<SetProjectLocationDialog
option={setLocationOption}
projectName={selectedProjectName}
projectKind={selectedRepoIsGit ? 'git' : 'folder'}
defaultCloneUrl={defaultCloneUrl}
onClose={handleSetLocationClose}
onReady={handleSetLocationReady}
/>
{setLocationDialogRequested.current ? (
<React.Suspense fallback={null}>
<SetProjectLocationDialog
option={setLocationOption}
projectName={selectedProjectName}
projectKind={selectedRepoIsGit ? 'git' : 'folder'}
defaultCloneUrl={defaultCloneUrl}
onClose={handleSetLocationClose}
onReady={handleSetLocationReady}
/>
</React.Suspense>
) : null}
</div>
)
}
@@ -31,10 +31,20 @@ import { ShortcutKeyCombo } from '@/components/ShortcutKeyCombo'
import { showOnboardingFromRenderer } from '../onboarding/show-onboarding-event'
import { SetupGuideProgressRing } from '../setup-guide/SetupGuideProgressRing'
import { useSetupGuideProgress } from '../setup-guide/use-setup-guide-progress'
import { SidebarFeedbackDialog } from './SidebarFeedbackDialog'
import { lazyWithRetry } from '@/lib/lazy-with-retry'
import { translate } from '@/i18n/i18n'
import { getUpdateCheckClickOptions, getUpdateCheckHint } from '@/lib/update-check-click-options'
// Why lazy: the feedback form is only reachable from this menu's own item, so it does not
// belong on the renderer boot graph.
const SidebarFeedbackDialog = lazyWithRetry(
() =>
import('./SidebarFeedbackDialog').then((module) => ({
default: module.SidebarFeedbackDialog
})),
{ reloadKey: 'sidebar-feedback-dialog' }
)
const DOCS_URL = 'https://www.onorca.dev/docs'
const CHANGELOG_URL = 'https://onorca.dev/changelog'
const GITHUB_URL = 'https://github.com/stablyai/orca'
@@ -95,6 +105,11 @@ export function SidebarSettingsHelpMenu(): React.JSX.Element {
const settingsShortcut = useShortcutKeyDetails('app.settings')
const [menuOpen, setMenuOpen] = useState(false)
const [feedbackOpen, setFeedbackOpen] = useState(false)
// Why sticky: the dialog animates itself closed off `open`, so unmounting on close cuts that short.
const feedbackDialogRequested = React.useRef(false)
if (feedbackOpen) {
feedbackDialogRequested.current = true
}
const [isRestartingOrca, setIsRestartingOrca] = useState(false)
const lastShowOnboardingAtRef = React.useRef(0)
const updateCheckModifiersRef = React.useRef(NO_UPDATE_CHECK_MODIFIERS)
@@ -330,7 +345,11 @@ export function SidebarSettingsHelpMenu(): React.JSX.Element {
</DropdownMenuContent>
</DropdownMenu>
</div>
<SidebarFeedbackDialog open={feedbackOpen} onOpenChange={setFeedbackOpen} />
{feedbackDialogRequested.current ? (
<React.Suspense fallback={null}>
<SidebarFeedbackDialog open={feedbackOpen} onOpenChange={setFeedbackOpen} />
</React.Suspense>
) : null}
</>
)
}