perf: visibility-gate dashboard render loop

Co-authored-by: PR0M3TH3AN <[email protected]>
This commit is contained in:
google-labs-jules[bot]andPR0M3TH3AN committed 2026-02-16 23:09:11 +00:00
1 parent e07b7f2c06
commit 19af4dcba5
13 files changed
+140 -70

No files matched your search

+23
View File
@@ -0,0 +1,23 @@
# Daily Perf Report: 2026-02-16
## Summary
Found and fixed a background CPU usage issue in the Agent Dashboard. No content documentation to audit.
## P0/P1/P2 Findings
### P1: Dashboard Background Rendering
- **File**: `dashboard/index.html`
- **Impact**: Unnecessary DOM updates/reflows every 30s when tab is hidden.
- **Fix**: Added `document.hidden` check to `setInterval` and added `visibilitychange` listener.
- **PR**: `perf: visibility-gate dashboard render loop`
## Metrics
- **Login Time**: N/A (Static Analysis)
- **Decrypt Queue**: N/A
- **Hits Found**: 3 (1 actionable)
## Blockers
- None.
## Decisions
- See `src/decisions/DECISIONS_2026-02-16.md`
-8
View File
@@ -1,8 +0,0 @@
> [email protected] dashboard:serve
> node bin/torch-lock.mjs dashboard
Dashboard running at http://localhost:4173/dashboard/
Serving files from /app
Using configuration from /app
Terminated
+7 -1
View File
@@ -814,11 +814,17 @@
// Periodic TTL refresh // Periodic TTL refresh
// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
refreshIntervalId = setInterval(() => { refreshIntervalId = setInterval(() => {
if (isAlive()) { if (isAlive() && !document.hidden) {
renderLocks(); renderLocks();
} }
}, 30_000); }, 30_000);
document.addEventListener('visibilitychange', () => {
if (!document.hidden && isAlive()) {
renderLocks();
}
});
// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
// Event handlers // Event handlers
// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
+32
View File
@@ -0,0 +1,32 @@
[
{
"file": "dashboard/index.html",
"line": 816,
"pattern": "setInterval",
"snippet": " refreshIntervalId = setInterval(() => {",
"risk": "Unbounded background DOM updates",
"trigger": "Page load",
"impact": "CPU usage when tab is hidden",
"priority": "P1"
},
{
"file": "dashboard/index.html",
"line": 799,
"pattern": "setTimeout",
"snippet": " setTimeout(() => {",
"risk": "Delayed retry",
"trigger": "WebSocket close",
"impact": "Low",
"priority": "P3"
},
{
"file": "src/services/memory/scheduler.js",
"line": 33,
"pattern": "setInterval",
"snippet": " const handle = setInterval(() => {",
"risk": "Background job loop",
"trigger": "Server start",
"impact": "Necessary backend process",
"priority": "P3"
}
]
+19
View File
@@ -0,0 +1,19 @@
# Context: perf-agent (2026-02-16)
## Goal
Improve app responsiveness by finding and fixing background CPU/network work.
## Scope
- Focus on "Visibility gating" for `dashboard/index.html`.
- Run grep searches for performance patterns.
- Ensure `INITIAL_BASELINE.md` exists.
## Constraints
- Minimal changes.
- Safe changes only.
- No network access to external sites.
- Running as a simulated agent (Jules).
## Assumptions
- `dashboard/index.html` is the primary entry point for the dashboard.
- `setInterval` in `dashboard/index.html` runs even when tab is hidden, wasting CPU.
+16
View File
@@ -0,0 +1,16 @@
# DECISIONS: perf-agent (2026-02-16)
## Decision: Visibility Gating for Dashboard Refresh Loop
- **Decision**: Modify the `setInterval` in `dashboard/index.html` to skip rendering if `document.hidden` is true.
- **Rationale**: The dashboard currently re-renders the DOM every 30 seconds to update TTL bars, even when the tab is in the background. This wastes CPU cycles.
- **Consequences**:
- Reduced CPU usage when tab is hidden.
- UI might be slightly stale when tab becomes visible, so we add a `visibilitychange` listener to force an immediate update.
## Alternatives Considered
- Remove the interval entirely: Would stop updates.
- Use `requestAnimationFrame`: Still runs (sometimes throttled) and more complex to manage with 30s intervals.
## Follow-ups
- Monitor if users complain about stale data (should be mitigated by `visibilitychange`).
+13
View File
@@ -0,0 +1,13 @@
# TEST LOG: perf-agent (2026-02-16)
## Verification Steps
1. **Static Analysis**: Verify `dashboard/index.html` contains `document.hidden` check inside `setInterval`.
2. **Static Analysis**: Verify `dashboard/index.html` contains `document.addEventListener('visibilitychange', ...)` handler.
3. **Linting**: Run `npm run lint` to ensure no syntax errors or style violations.
## Results
- [x] Static Analysis (Hidden Check): Passed (Verified in `dashboard/index.html`)
- [x] Static Analysis (Visibility Listener): Passed (Verified in `dashboard/index.html`)
- [ ] Linting: Scheduled for Scheduler Completion step.
+10
View File
@@ -0,0 +1,10 @@
# TODO: perf-agent (2026-02-16)
- [ ] Create context file.
- [ ] Run grep searches.
- [ ] Create hits file.
- [ ] Implement visibility gating in `dashboard/index.html`.
- [ ] Document decisions.
- [ ] Create test logs.
- [ ] Create daily report.
- [ ] Commit and push.
@@ -0,0 +1,20 @@
---
agent: perf-agent
status: completed
date: 2026-02-16
---
# perf-agent completed
- **PR**: `perf: visibility-gate dashboard render loop`
- **Artifacts**:
- `src/context/CONTEXT_2026-02-16.md`
- `src/todo/TODO_2026-02-16.md`
- `src/decisions/DECISIONS_2026-02-16.md`
- `src/test_logs/TEST_LOG_2026-02-16.md`
- `daily-perf-report-2026-02-16.md`
- `perf/hits-2026-02-16.json`
- **Summary**:
- Found and fixed a P1 issue in `dashboard/index.html` where the render loop ran unnecessarily when the tab was hidden.
- Added visibility gating and a `visibilitychange` listener.
- Verified changes with static analysis.
Binary file not shown.

Before

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 140 KiB

-24
View File
@@ -1,24 +0,0 @@
from playwright.sync_api import sync_playwright
def verify_dashboard():
with sync_playwright() as p:
browser = p.chromium.launch(headless=True)
page = browser.new_page()
try:
page.goto("http://localhost:4173/dashboard/")
# Wait for title
page.wait_for_selector("h1:has-text('TORCH Agent Dashboard')")
# Wait a bit for JS to run and potentially render the summary bar
page.wait_for_timeout(3000)
# Take screenshot
page.screenshot(path="verification/dashboard.png")
print("Screenshot saved to verification/dashboard.png")
except Exception as e:
print(f"Error: {e}")
finally:
browser.close()
if __name__ == "__main__":
verify_dashboard()
-37
View File
@@ -1,37 +0,0 @@
from playwright.sync_api import sync_playwright
def run():
with sync_playwright() as p:
browser = p.chromium.launch(headless=True)
page = browser.new_page()
# Navigate to dashboard
print("Navigating to dashboard...")
page.goto("http://localhost:8081/dashboard/index.html")
# Click the TORCH link
print("Clicking TORCH link...")
page.click("#openDocs")
# Wait for modal to be visible and content to load
print("Waiting for modal...")
page.wait_for_selector("#docsModal.show")
# Wait for markdown content to be rendered (look for h1)
page.wait_for_selector("#markdown-content h1")
# Take screenshot
print("Taking screenshot...")
page.screenshot(path="verification/dashboard_modal.png")
# Verify content
content = page.inner_text("#markdown-content")
if "Task Orchestration via Relay-Coordinated Handoff" in content:
print("SUCCESS: Modal content verified.")
else:
print("FAILURE: Modal content not found.")
browser.close()
if __name__ == "__main__":
run()