fix(app): make session navigation stable and fast#33569
Merged
Conversation
Contributor
There was a problem hiding this comment.
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]!), | ||
| ) |
699c77f to
fbb1428
Compare
# Conflicts: # packages/app/src/app.tsx # packages/app/src/pages/home.tsx
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Performance
Production Chromium, native speed, one worker. Painted-frame benchmarks sample with
requestAnimationFramefollowed bysetTimeout(0). Baseline is currentupstream/devate8610d821; 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
macOS
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.
Visual Stability
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.
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 typecheckacross 23 packagesbun run test:unit: 415 passedbun test ./e2e/performance/unit: 15 passedbun run test:e2e: 16 passedupstream/devand rebased branch refsNotes
bun run test:benchdiscovers all navigation scenarios above for future baseline comparisons