Skip to content

fix(app): make session navigation stable and fast#33569

Merged
Brendonovich merged 7 commits into
anomalyco:devfrom
Hona:perf/app-navigation
Jun 24, 2026
Merged

fix(app): make session navigation stable and fast#33569
Brendonovich merged 7 commits into
anomalyco:devfrom
Hona:perf/app-navigation

Conversation

@Hona

@Hona Hona commented Jun 24, 2026

Copy link
Copy Markdown
Member

Summary

  • keep the previous coherent session painted until destination placement is ready, without adding a loading screen
  • reuse bounded server/session placement and small opaque cursor pages to reduce cold navigation work
  • preload likely route modules, every open session tab, and the top home sessions with owned cleanup
  • prepare completed Markdown during the existing bounded home prefetch and stage review internals after session content
  • make titlebar tabs use authoritative cached session metadata before issuing another request
  • make one history action consume one opaque cursor page while preserving visible anchors and bounded continuation
  • add discoverable painted-frame benchmarks for cold/hot tabs, child sessions, new sessions, home-to-session content/tab paint, and single-tab close-to-home

Performance

Production Chromium, native speed, one worker. Painted-frame benchmarks sample with requestAnimationFrame followed by setTimeout(0). Baseline is current upstream/dev at e8610d821; branch is the PR head. First-navigation and home/close values are medians of 3 runs. Cold/hot tab values are medians of 15 trials (3 benchmark repetitions, each containing 5 trials).

Windows

Scenario Metric Before After Change
Cold session First correct paint 92.9 ms 20.7 ms 78% faster
Cold session Stable paint 108.4 ms 44.6 ms 59% faster
Child/subagent First correct paint 57.5 ms 39.3 ms 32% faster
Child/subagent Stable paint 72.4 ms 60.7 ms 16% faster
New session First correct paint 37.0 ms 38.1 ms 3% slower
New session Stable paint 65.3 ms 61.5 ms 6% faster
Cold tab First correct paint 67.9 ms 23.2 ms 66% faster
Cold tab Stable paint 134.1 ms 45.3 ms 66% faster
Hot tab First correct paint 24.0 ms 24.1 ms unchanged
Hot tab Stable paint 46.6 ms 46.4 ms unchanged

macOS

Scenario Metric Before After Change
Cold session First correct paint 58.6 ms 38.9 ms 34% faster
Cold session Stable paint 80.1 ms 46.7 ms 42% faster
Child/subagent First correct paint 56.9 ms 54.7 ms 4% faster
Child/subagent Stable paint 80.6 ms 63.8 ms 21% faster
New session First correct paint 48.3 ms 48.4 ms unchanged
New session Stable paint 80.0 ms 80.4 ms unchanged
Cold tab First correct paint 58.3 ms 41.2 ms 29% faster
Cold tab Stable paint 97.4 ms 47.3 ms 51% faster
Hot tab First correct paint 16.3 ms 16.4 ms unchanged
Hot tab Stable paint 47.7 ms 47.7 ms unchanged

Home And Tab Milestones

Home-to-session records session content and titlebar-tab visibility independently. Closing measures home shell, restored session row, and tab removal.

Platform Scenario Metric Before After Change
Windows Home → session Session content first paint 166.8 ms 79.8 ms 52% faster
Windows Home → session Titlebar tab first paint 166.8 ms 10.9 ms 93% faster
Windows Home → session Content + tab stable 190.1 ms 97.5 ms 49% faster
Windows Close only tab → home Home + row + tab removal first paint 81.0 ms 48.5 ms 40% faster
Windows Close only tab → home Stable paint 111.3 ms 78.5 ms 29% faster
macOS Home → session Session content first paint 110.4 ms 68.7 ms 38% faster
macOS Home → session Titlebar tab first paint 110.4 ms 36.0 ms 67% faster
macOS Home → session Content + tab stable 137.5 ms 82.1 ms 40% faster
macOS Close only tab → home Home + row + tab removal first paint 55.1 ms 54.5 ms unchanged
macOS Close only tab → home Stable paint 80.5 ms 64.0 ms 20% faster

Visual Stability

Metric Before After
Cold session blank frames 1-3 0
Child/subagent blank frames 2 0
Cached tab blank/wrong frames 0 0
Streaming bottom drift 0 0
Timeline/Markdown remounts 0 0

Chrome Trace Attribution

Full Chrome Performance traces include V8 sampling and timeline-stack overhead, so these values are reported separately from the native-speed medians above. User Timing marks delimit click, first paint, and stable paint inside each trace.

Platform Trace metric Previous branch Latest branch Change
Windows Home → content first paint 163.1 ms 104.7 ms 36% faster
Windows Long synchronous mount task 135.8 ms 85.9 ms 37% shorter
macOS Home → content first paint 95.6 ms 81.4 ms 15% faster
macOS Long synchronous mount task 53.9 ms 42.1 ms 22% shorter

The remaining traced cost is dominated by final Solid/DOM construction and layout rather than network or Markdown parsing. Review-shell geometry remains immediate; only its internal body is staged after the first session-content paint.

Verification

  • bun turbo typecheck across 23 packages
  • bun run test:unit: 415 passed
  • UI tests: 58 passed
  • bun test ./e2e/performance/unit: 15 passed
  • bun run test:e2e: 16 passed
  • timeline smoke, delayed cursor prepend, all-open-tab prefetch, collapse state, context resize, prompt hydration, Markdown cache, and virtualizer browser tests
  • 320-turn, 160-delta streaming stress: every delta delivered, zero blank samples, zero bottom drift, zero timeline/Markdown replacement
  • repeated production benchmarks on macOS and Windows against exact current upstream/dev and rebased branch refs

Notes

  • no loading page, splash, CSS, copy, or intentional visual design change
  • the existing message API remains in use; pagination is tested with opaque cursor tokens
  • bun run test:bench discovers all navigation scenarios above for future baseline comparisons

@Hona Hona requested a review from Brendonovich as a code owner June 24, 2026 01:45
Copilot AI review requested due to automatic review settings June 24, 2026 01:45

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR focuses on improving session navigation paint stability and latency in the app by caching session “placement” (server + directory + root) to avoid cold route work, switching history pagination to single opaque-cursor pages, and adding performance benchmarks to guard the new behavior.

Changes:

  • Add a bounded session placement cache and wire it into home/session navigation and titlebar tab metadata to reduce cold navigations.
  • Adjust timeline history paging to consume exactly one opaque cursor page per action, with controlled continuation when the user is already at the top.
  • Add/expand e2e performance probes + fixtures to measure first/stable paints for navigation milestones and first navigation blank-frame behavior.

Reviewed changes

Copilot reviewed 26 out of 26 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
packages/app/src/utils/session-placement.ts New bounded placement store used to resolve directory/root quickly across navigations.
packages/app/src/utils/session-placement.test.ts Unit tests for placement aliasing, inheritance, and bounding behavior.
packages/app/src/pages/session/timeline/model.ts Simplifies “load older” to a single page per call (opaque cursor semantics).
packages/app/src/pages/session/timeline/model.test.ts Updates tests to reflect single-page history loading behavior.
packages/app/src/pages/session.tsx Adds request/continuation coordination for history paging and cleanup for scheduled frames.
packages/app/src/pages/session-module.ts Adds shared dynamic import wrapper for session module preloading.
packages/app/src/pages/home.tsx Preloads session module; prefetches top sessions; sets placement before navigation; adds tabs usage.
packages/app/src/pages/home-module.ts Adds shared dynamic import wrapper for home module preloading.
packages/app/src/pages/directory-layout.tsx Inherits placement for child-session navigation to keep destination placement ready.
packages/app/src/context/global.tsx Registers the global sessionPlacement store alongside existing global contexts.
packages/app/src/context/directory-sync.ts Reduces initial message page size to support small-page navigation/pagination strategy.
packages/app/src/components/titlebar.tsx Uses cached placement + local sync data for tab titles before falling back to network; preloads home module.
packages/app/src/app.tsx Switches session-route resolution from query placeholdering to resource + placement cache.
packages/app/e2e/utils/mock-server.ts Introduces opaque cursor tokens for message pagination in e2e mock server.
packages/app/e2e/smoke/session-timeline.spec.ts Makes timeline key sampling robust by collecting currently visible timeline part IDs.
packages/app/e2e/performance/unit/timeline-test-helpers.test.ts Adds unit test for stress-session link builder.
packages/app/e2e/performance/unit/navigation-milestones.test.ts Adds unit test for milestone first/stable paint summarization.
packages/app/e2e/performance/unit/first-navigation-metrics.test.ts Adds unit tests for first-navigation blank-frame/stability summarization.
packages/app/e2e/performance/timeline/timeline-test-helpers.ts Updates stress helpers for server-scoped routes, draft tabs, and fixture paging.
packages/app/e2e/performance/timeline/session-timeline-stress.fixture.ts Extends fixture with child session + tool metadata to exercise child navigation.
packages/app/e2e/performance/timeline/navigation-milestones.ts Adds probe + summarizer for content/tab/home/tab-removed milestone paints.
packages/app/e2e/performance/timeline/home-tab-navigation-benchmark.spec.ts Adds benchmarks for home→session and close-only-tab→home milestone paints.
packages/app/e2e/performance/timeline/first-navigation-probe.ts Adds probe for detecting blank frames during first navigation to destination.
packages/app/e2e/performance/timeline/first-navigation-metrics.ts Adds summarizer for first navigation samples (blank/source/destination).
packages/app/e2e/performance/timeline/first-navigation-benchmark.spec.ts Adds benchmarks for unvisited tab, new-session draft, and child session first-navigation paint.
packages/app/e2e/performance/README.md Documents additional benchmark scenarios covered by the suite.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@@ -0,0 +1,41 @@
import { ServerConnection } from "@/context/server"
}
const absolute = (path: string) => (current()[0].path.directory + "/" + path).replace("//", "/")
const initialMessagePageSize = 80
const initialMessagePageSize = 2
Comment on lines +12 to +14
const stable = samples.findIndex(
(sample, index) => matches(sample) && matches(samples[index + 1]!) && matches(samples[index + 2]!),
)
@Hona Hona force-pushed the perf/app-navigation branch from 699c77f to fbb1428 Compare June 24, 2026 02:02
# Conflicts:
#	packages/app/src/app.tsx
#	packages/app/src/pages/home.tsx
@Brendonovich Brendonovich enabled auto-merge (squash) June 24, 2026 07:39
@Brendonovich Brendonovich merged commit a4551a9 into anomalyco:dev Jun 24, 2026
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants