Uh oh!
There was an error while loading. Please reload this page.
perf(web): defer pull request line stats until visible - #6471
Conversation
Important Review skippedAuto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Comment |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
ApprovabilityVerdict: Not approved Macroscope's review found this PR not approvable — This changes the default pull-request list’s stats-loading behavior and adds substantial observer, batching, caching, refresh, and sort-dependent request lifecycle logic. The interaction between viewport visibility, pagination, sorting, and refresh warrants human review. You can add or adjust custom eligibility rules. Learn more. |
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
One finding on the new visibility-driven stats observer: the rootMargin lookahead is inert because the observer uses the implicit viewport root while the list scrolls inside the page's own overflow-y-auto container, so line counts land after rows are already on screen and reflow the row's right column in view.
Posted via Macroscope — UI Consistency
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Dismissing prior approval to re-evaluate 61e36cb
61e36cb to
988f481CompareUh oh!
There was an error while loading. Please reload this page.
e467145 to
2b197e3CompareUh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 27f2176. Configure here.
Uh oh!
There was an error while loading. Please reload this page.
71326c8 to
bf29367CompareUh oh!
There was an error while loading. Please reload this page.
Co-authored-by: Theo Browne <me@t3.gg>
Co-authored-by: Theo Browne <me@t3.gg>
## What's Changed * perf(server): scan only appended transcript bytes for usage summaries by @StiensWout in pingdotgg/t3code#9024 * perf(server): cut chatty tool-update frames by 90% by @Adamulek123 in pingdotgg/t3code#8368 * fix(server): settle threads server-side by @t3dotgg in pingdotgg/t3code#8600 * fix(clients): dedupe skills in composer menus by @Adamulek123 in pingdotgg/t3code#8043 * fix(server): stop OpenCode child sessions by @t3dotgg in pingdotgg/t3code#9005 * perf(web): defer pull request line stats until visible by @Adamulek123 in pingdotgg/t3code#6471 * perf(server): skip full-message reads while streaming by @t3dotgg in pingdotgg/t3code#9032 * perf(client-runtime): halve server config bootstrap traffic by @Adamulek123 in pingdotgg/t3code#8367 **Full Changelog**: pingdotgg/t3code@v0.0.38-nightly.20260901.1245...v0.0.38-nightly.20260901.1246 Upstream release: https://github.com/pingdotgg/t3code/releases/tag/v0.0.38-nightly.20260901.1246
## What's Changed * Add mobile composer attachment menu with video support by @juliusmarminge in pingdotgg/t3code#8843 * fix(web): restore unified activity logs and composer banners by @t3dotgg in pingdotgg/t3code#8734 * fix(web): address composer banner review follow-ups by @juliusmarminge in pingdotgg/t3code#8850 * fix(web): widen sync banners and simplify the working timer by @juliusmarminge in pingdotgg/t3code#8855 * fix(preview): improve browser recording quality by @maria-rcks in pingdotgg/t3code#8839 * fix(web): mark pull request links as external by @juliusmarminge in pingdotgg/t3code#8856 * fix(mobile): replace Callstack glass with Expo glass by @juliusmarminge in pingdotgg/t3code#8862 * fix(server): skip IDE detection in Claude probes by @yashranaway in pingdotgg/t3code#8634 * chore(macroscope): review diagnostic overrides by @t3-code[bot] in pingdotgg/t3code#8917 * fix(contracts): accept CLI event origins by @nateEc in pingdotgg/t3code#8905 * fix(web): hide invalid slash skill completions by @nateEc in pingdotgg/t3code#8904 * fix(mobile): defer draft navigation until submission completes by @juliusmarminge in pingdotgg/t3code#8914 * chore: disable CodeRabbit review status by @juliusmarminge in pingdotgg/t3code#8933 * Delete app.json by @juliusmarminge in pingdotgg/t3code#8934 * fix(web): show scrollbar for wide markdown tables by @UtkarshUsername in pingdotgg/t3code#8868 * fix(mobile): shimmer active tool rows by @juliusmarminge in pingdotgg/t3code#8932 * chore(deps): bump Electron to 43.4.1 by @StiensWout in pingdotgg/t3code#8626 * fix(chat): smooth worktree setup status by @juliusmarminge in pingdotgg/t3code#8922 * feat(mobile): add video playback with native iOS controls by @juliusmarminge in pingdotgg/t3code#8919 * fix(web): prevent chat metadata overlap by @MatthewFeroz in pingdotgg/t3code#8851 * fix(server): preserve usage cache outside walked roots by @Lucenx9 in pingdotgg/t3code#8540 * feat(mobile): add native image and PDF previews by @juliusmarminge in pingdotgg/t3code#8959 * fix(server): allow long thread IDs in HTTP routes by @nateEc in pingdotgg/t3code#8898 * fix(shared): preserve Windows shell PATH priority by @UtkarshUsername in pingdotgg/t3code#8748 * fix(web): make WSL settings searchable by @UtkarshUsername in pingdotgg/t3code#8881 * feat(web): add expand/collapse all control to the files surface by @UtkarshUsername in pingdotgg/t3code#8889 * feat(mobile): upload attachments while composing by @juliusmarminge in pingdotgg/t3code#8978 * fix(chat): keep agent activity visible between actions by @maria-rcks in pingdotgg/t3code#8984 * fix(server): isolate remote web session cookies by @Bil0000 in pingdotgg/t3code#8085 * feat(pull-requests): link GitHub references in markdown by @maria-rcks in pingdotgg/t3code#8812 * perf(server): reduce frequency of full tool call output being loaded into memory from db by @t3dotgg in pingdotgg/t3code#8988 * feat(web): add pull request list filters by @maria-rcks in pingdotgg/t3code#8809 * feat(web): search individual settings by detail by @maria-rcks in pingdotgg/t3code#8831 * feat(client): render viewed images in work logs by @maria-rcks in pingdotgg/t3code#8936 * fix(client): use package import for markdown image helpers by @juliusmarminge in pingdotgg/t3code#9010 * test: remove static presentation snapshots by @t3-code[bot] in pingdotgg/t3code#9008 * perf(server): bound snapshot activity payload memory by @t3dotgg in pingdotgg/t3code#9000 * perf(server): cut idle CPU use and stop provider event leaks by @t3dotgg in pingdotgg/t3code#8187 * perf(server): scan only appended transcript bytes for usage summaries by @StiensWout in pingdotgg/t3code#9024 * perf(server): cut chatty tool-update frames by 90% by @Adamulek123 in pingdotgg/t3code#8368 * fix(server): settle threads server-side by @t3dotgg in pingdotgg/t3code#8600 * fix(clients): dedupe skills in composer menus by @Adamulek123 in pingdotgg/t3code#8043 * fix(server): stop OpenCode child sessions by @t3dotgg in pingdotgg/t3code#9005 * perf(web): defer pull request line stats until visible by @Adamulek123 in pingdotgg/t3code#6471 * perf(server): skip full-message reads while streaming by @t3dotgg in pingdotgg/t3code#9032 * perf(client-runtime): halve server config bootstrap traffic by @Adamulek123 in pingdotgg/t3code#8367 * fix(web): align un-settle banner action by @StiensWout in pingdotgg/t3code#9033 * fix(web): block type-to-focus behind open dialogs by @Lucenx9 in pingdotgg/t3code#8139 * feat(shortcuts): copy active thread reference by @maria-rcks in pingdotgg/t3code#8994 * fix(mobile): keep thread scroll bounds current after animations by @juliusmarminge in pingdotgg/t3code#9013 * fix(server): cache project favicon resolution by @willsheldon in pingdotgg/t3code#9080 * feat(claude): add Claude Fable 5.1 model by @q1 in pingdotgg/t3code#9078 * fix(preview): restore recording and macOS rendering after Electron 43 by @StiensWout in pingdotgg/t3code#9001 * feat(desktop): add configurable quit shortcut confirmation by @juliusmarminge in pingdotgg/t3code#9076 * feat(web): open project settings from thread menus by @SunkenInTime in pingdotgg/t3code#8925 * fix(chat): reuse one row for live activity by @maria-rcks in pingdotgg/t3code#9062 * feat(models): discover Claude models from remote manifest by @juliusmarminge in pingdotgg/t3code#9084 * Revert "fix(chat): reuse one row for live activity" by @maria-rcks in pingdotgg/t3code#9096 * fix(web): sync sidebar PR state from open panel by @t3-code[bot] in pingdotgg/t3code#9092 * fix(web): changing projects no longer creates a draft by @extoci in pingdotgg/t3code#9097 * fix(web): keep theme placeholder text dimmer than entered text by @flamboh in pingdotgg/t3code#9104 * fix(web): keep the selected environment when changing projects by @t3dotgg in pingdotgg/t3code#9102 ## New Contributors * @willsheldon made their first contribution in pingdotgg/t3code#9080 * @q1 made their first contribution in pingdotgg/t3code#9078 **Full Changelog**: pingdotgg/t3code@v0.0.37...v0.0.38 Upstream release: https://github.com/pingdotgg/t3code/releases/tag/v0.0.38
Co-authored-by: Theo Browne <me@t3.gg>
Co-authored-by: Theo Browne <me@t3.gg>

Pull request line counts used to load for every row, including rows far outside the viewport. Large lists could send hundreds of expensive host stat reads before the user reached those rows.
This change uses one list-owned observer to request stats for rows near the viewport. It groups stable requests by environment, keeps received counts cached, and does not add active or cached rows to later batches.
Largest and smallest sorting still requests stats for every loaded row because those counts decide the row order. Manual refresh uses the same policy. Each environment batch stays within the 500-ref contract limit. If the filter or sort policy changes while a manual refresh waits for host invalidation, the stale stats refresh is ignored.
This modernizes @Adamulek123's original implementation on current
mainwhile preserving the new row layout, filters, facet refresh, scroll behavior, and sorting.Validation
vp test run apps/web/src/components/pullRequest/pullRequestList.logic.test.ts(102 tests passed)vp run --filter @t3tools/web typecheckgit diff --check origin/main...HEADNo browser test was run for this logic and request-lifetime change.
Modernized by GPT-5.6 Sol in the Codex harness. Original implementation by @Adamulek123.
Note
Medium Risk
Touches request lifetime, refresh races, and sort-dependent data loading on a high-traffic list; logic is heavily unit-tested but browser behavior was not validated.
Overview
Pull request diff line counts are no longer fetched for every loaded row. The list now drives stats through a shared
IntersectionObserveron the scroll container, with eachPullRequestRowregistering viastatsRefanddata-pull-request-stats-key.New logic in
pullRequestList.logicbatches refs per environment (max 500 per batch), skips rows already in-flight or cached, prunes completed batches when rows scroll away, and choosesvisiblevseagerpolicy from sort mode (largest/smallest still loads all rows). Manual refresh re-requests only under the current filter/policy scope.usePullRequestListStats/ merged environment queries gainisPendingand targetedrefresh(override)so refresh does not blindly re-hit every prior batch. Pagination and header observers now share the parentscrollRefinstead of the viewport.Reviewed by Cursor Bugbot for commit 18e9cdf. Bugbot is set up for automated code reviews on this repo. Configure here.
Note
Defer pull request diff-stat fetches until rows are visible
IntersectionObserveron each row button.eagerpolicy that requests stats for all loaded rows; other sorts use avisiblepolicy that only requests stats for rows currently on screen.pullRequestStatsRefreshBatches, ignoring late refreshes when the filter or policy has changed; completed batches whose rows have left the viewport are pruned withretainVisiblePullRequestStatsBatches.PullRequestRowgainsstatsKey/statsRefprops and adata-pull-request-stats-keyattribute;PullRequestsColumnnow receives a sharedscrollRefso list paging and stats observers share one scroll root.usePullRequestListStatsnow exposesisPendingand accepts an explicittargetsoverride on refresh.scrollRefroot with the list paging observer, so any consumer overridingPullRequestsColumn's scroll container must pass a valid ref.Macroscope summarized 18e9cdf.