perf(hooks): pause background pollers when page is hidden#602
Open
HUQIANTAO wants to merge 4 commits into
Open
perf(hooks): pause background pollers when page is hidden#602HUQIANTAO wants to merge 4 commits into
HUQIANTAO wants to merge 4 commits into
Conversation
added 4 commits
June 3, 2026 01:09
Three flex flex-col containers in ChatListPanel had no gap, so adjacent SessionListItem hover backgrounds merged into one band when the cursor swept between rows. - L546: project group body (新建项目 + 项目列表) - L618: visibleSessions list inside the project group - L741: assistant group body (助理 flat list) Add gap-1.5 (6px) — symmetric with px-3 / h-8 row padding, and the smallest gap that still reads as separation under bg-sidebar-accent hover (~6% black overlay on light theme). SessionListItem.tsx L218 inner-stack gap-0.5 intentionally stays — outer rhythm and inner rhythm are different problems and should not collapse onto the same value. Pure className change: 3 lines, all stock Tailwind utilities, zero business logic touched.
Two 2xl-style scrolling dialogs had footers with no visual separator from the last form field above. The Cancel / Save / Test / Connect buttons read as part of the same visual block as the configuration rows, defeating the 'decision exit' affordance. - ModelsSection.tsx (Role mapping dialog, L1960): footer welded to last role assignment row. - PresetConnectDialog.tsx (preset connect/edit, L809): footer welded to last advanced field (model mapping grid + extraEnv + headers + envOverrides textareas). Add to both: shrink-0 gap-2 border-t border-border/50 pt-5 mt-3 - shrink-0 keeps the footer pinned when the dialog scrolls - border-t gives the 1px anchor; pt-5 + mt-3 give the 32px stack Implementation rule (now in ui-governance.md): footer anchor is applied at the call site, not in the DialogFooter primitive, so short dialogs (confirm / add-model) keep their minimal footer without a stray divider. Pure className change: 2 lines, all stock Tailwind utilities, zero business logic touched.
Tokenize the two spacing patterns that motivated this PR so the
next sidebar list or 2xl dialog has a clear analogy anchor instead
of picking 0/2/4/8 from gut feel:
- docs/ui-governance.md: new '间距规范' section
- sidebar list rhythm: 2px (cell-internal) vs 6px (between-item)
- dialog footer anchor: border+pt for 2xl scrolling, none for
short dialogs
- implementation rule: className at call site, primitive untouched
- 6px rationale (2px merges with hover bg; 8px compounds on long
lists; 6px is the smallest reliable separator)
- docs/exec-plans/active/sidebar-list-spacing.md (audit trail):
problem matrix, fix matrix, decision log, smoke-test cases.
- docs/insights/sidebar-list-2px-vs-6px.md (context):
why outer-rhythm and inner-rhythm must not collapse onto the
same value; why ModelsSection AND PresetConnectDialog are
fixed together (same bug pattern, same fix, same review path).
Pause useBridgeStatus and useNotificationPoll when document.visibilityState is hidden. The Electron main process already covers the hidden case via its bg-notify timer, and waking the renderer every 5s just to drain an empty queue is wasted CPU and network. On resume we run an immediate catch-up poll so the user sees fresh data without waiting for the next interval tick.
|
Someone is attempting to deploy a commit to the op7418's projects Team on Vercel. A member of the Team first needs to authorize it. |
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.
Problem
Two renderers poll long-lived endpoints every 5 seconds, even when the user has the app in a background tab:
useBridgeStatus—setInterval(refreshStatus, 5000)while the bridge is runninguseNotificationPoll—setInterval(poll, POLL_INTERVAL)unconditionally on mountThe Electron main process already covers the hidden case via its
bgNotifyTimerand only runs when!mainWindow.isVisible(). The renderer's polls are duplicate work: 12 wakeups per minute per hidden tab, each firing a fetch + JSON parse on a thread the user can't see.This was the same root cause as the previously-shipped PR #600 for git-status polling.
Fix
Gate both intervals on
document.visibilityState === 'visible':visible→ start the interval; onhidden→clearIntervaland null the refvisibilitychange→ resume runs an immediate catch-up poll so the UI shows fresh data without waiting for the next tickThe visible/hidden listener and the interval share the same
pollRef/timerRef, so a tear-down or remount is race-free.Impact
GET /api/bridge+GET /api/tasks/notifyround-trips per minute per hidden windowsetIntervalwaking the renderer event loop on background tabs