Repository navigation
Conversation
Each boring-sidebar folder header subscribed to the whole local visit map, so any thread visit re-rendered every folder header, open ones included. The header now selects its derived status dot instead, so it re-renders only when its own dot changes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ApprovabilityVerdict: Approved at Macroscope's review found this PR approvable — Folder headers now subscribe to their computed status instead of the entire visit-history map, avoiding unnecessary re-renders. This is a localized rendering optimization with unchanged status logic and sidebar actions. You can add or adjust custom eligibility rules. Learn more. |
|
No actionable comments were generated in the recent review.
|
| Layer / File(s) | Summary |
|---|---|
Resolve folder dots from local visit state apps/web/src/components/sidebar/SidebarProjectFolderHeader.tsx, apps/web/src/components/sidebar/SidebarProjectFolderHeader.browser.test.tsx |
The header reads threadLastVisitedAtById when resolving the dot for a collapsed folder and keeps the dot null when expanded. Browser tests check done labels from local timestamps and verify render behavior for relevant and unrelated visit updates. |
Estimated code review effort: 2 (Simple) | ~10 minutes
Change: Refactor
Possibly related PRs
- pingdotgg/t3code#21039: Adds the project-folder header and dot resolver that this change updates.
- pingdotgg/t3code#26690: Changes the
treeitemrole used by this PR’s browser test to locate headers. - pingdotgg/t3code#25663: Changes dot resolution behavior used by the folder header.
Suggested labels: size:S
Suggested reviewers: t3dotgg, juliusmarminge
Merge Risk: 
Minimal · up to b5b69
-
No actionable merge-blocking risk was identified for the folder-header change.
Pre-merge checks: 
4
-
Full details: Title check
-
Explanation
The title names the main change: sidebar folder headers no longer re-render on every thread visit. The raw summary and objectives confirm that each header now selects its derived dot from the store, so it re-renders only when its own dot changes. The title follows the conventional commit format with a 'perf(web)' scope and is specific enough for a reviewer scanning history. It is 75 characters, which is within a reasonable length.
Full details: Description check
-
Explanation
The description covers the required template sections. Problem: every folder header subscribed to the whole local visit map, so unrelated visits re-rendered open and closed headers. Change: each header selects its dot through a store selector, and the selector returns a string or null. Scope and approval: the author explains why prior approval is not needed for a narrow internal performance fix and cites related PRs. Verification: the author lists a new browser test, before/after render counts (120 on main versus 0 with the PR), a check with
#28616applied, and a check:changed run. The author also states what was not checked, including screenshots, wall-clock timing, and desktop runs. The description does not link a triaged issue or maintainer approval. The template asks for that link, or for an explanation of why the fix qualifies without one. The author gives that explanation, but it is a self-assessment and not a maintainer sign-off. The description also includes a model attribution line, which the template requests. The description is mostly complete, so it passes.
-
Finishing Touches
-
Generate unit tests (beta)
-
- Create a new PR
-
- Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts
Usage-based review receipt
- Mode: Continue automatically
- Reviewed files: 2
- Charged: $0.50
- View usage details
Note
This review was completed with usage-based billing: files reviewed beyond your plan's included limits are billed at $0.25/file. View usage-based billing.
Problem
In the boring sidebar, every project folder header subscribed to the whole local visit map. Any change to that map re-rendered every folder header, open folders included, even though only a closed folder's own hidden threads can change its dot.
That map changes on Mark unread, on acknowledging a woken thread, and, for environments on older servers without visit tracking, on every update of the open thread. That is several times a second while a reply streams. So with older servers, every folder header re-rendered several times a second during any reply.
Change
The header now selects its derived dot from the store instead of the map. The selector runs the same
resolveSidebarFolderDotover the same inputs, and it returns a string ornull, so the header re-renders only when its own dot changes. Open folders never re-render from visits. This is the same approach #23124 took for ChatView.The dot, its screen-reader label, the count and folder state are unchanged.
Scope and approval
This is a narrow internal performance fix in one component with no behavior change, so it should not need prior approval. #28616 (open) changes
resolveSidebarFolderDotso that opening a failed thread clears the failed dot. The selector calls that same function, so the two compose. See Verification.Verification
SidebarProjectFolderHeader.browser.test.tsx(new) renders two closed folders in Chromium. An unrelated visit re-renders neither header. A visit to one folder's unread thread clears its "done" dot, and Mark unread on the other folder's thread adds one. Each header re-renders exactly once for its own change. Onmainthe unrelated-visit assertion fails because both headers re-render.Render counts from a wider version of that test, with 6 folders (3 open, 3 closed) and 20 visits to an unrelated thread, the pattern an older server produces while a reply streams:
mainA relevant visit re-rendered only the affected header, once.
With fix(web): clear failed badges when threads are opened #28616's
Sidebar.logic.tsapplied on top: the failed dot showed, an unrelated visit caused no re-render, and visiting the failed thread cleared the dot with one re-render. The same check fails without fix(web): clear failed badges when threads are opened #28616, as expected.vp run check:changed 1d626d02d95f9a2343553f6498037ee82290d304(format, lint, knip, typecheck, tests, React Compiler) passes.Not checked:
Prior PRs
No earlier PR made this change. #21039 by t3dotgg added the folder headers. #23124 by juliusmarminge applied the same narrowing to ChatView.
Generated with Claude Opus 5.5 and GPT-6.1 Sol in T3 Code Nightly