diff --git a/context/CONTEXT_2026-02-17_06-33-23.md b/context/CONTEXT_2026-02-17_06-33-23.md new file mode 100644 index 00000000..aeae2029 --- /dev/null +++ b/context/CONTEXT_2026-02-17_06-33-23.md @@ -0,0 +1,4 @@ +# Context for Perf Agent Tue Feb 17 06:33:23 UTC 2026 + +Goal: Daily performance improvement. +Scope: Scan codebase for perf issues, fix one if safe, audit docs. diff --git a/daily-perf-report-2026-02-17.md b/daily-perf-report-2026-02-17.md new file mode 100644 index 00000000..1fd23d90 --- /dev/null +++ b/daily-perf-report-2026-02-17.md @@ -0,0 +1,30 @@ +# Daily Performance Report - 2026-02-17 + +**Summary**: Identified and fixed background CPU usage in `ExploreDataService` when the tab is hidden. Found unbounded concurrency in `RelayHealthService`. + +## Findings + +### P1: Background Interval Leaks (Fixed) +- **File**: `js/services/exploreDataService.js` +- **Issue**: `startIntervals()` initiated recurring timers (watch history sync, tag IDF calc) even if `document.hidden` was true at startup (e.g., background tab load). +- **Impact**: Wasted CPU and network in background tabs. +- **Fix**: Added explicit `document.hidden` check in `startIntervals`. + +### P2: Unbounded Concurrency (Identified) +- **File**: `js/services/relayHealthService.js` +- **Issue**: `refresh()` uses `Promise.allSettled(urls.map(...))` to check all relays simultaneously. +- **Impact**: Can spike network connections (N+1) if the relay list is large. +- **Recommendation**: Implement a concurrency pool (e.g., limit to 3 parallel checks). + +### Linting Issues +- `npm run lint:hex` failed with `ENOBUFS` due to large `js/webtorrent.min.js`. +- **Fix**: Increased `spawnSync` buffer size in `scripts/check-hex.js` and added exclusion (though git grep exclusion logic seems flaky for this file). + +## Metrics +- **Login Time**: Not measured this run. +- **Background CPU**: Expected reduction in background tab CPU usage due to `ExploreDataService` fix. + +## Actions Taken +- [x] Patched `js/services/exploreDataService.js`. +- [x] Patched `scripts/check-hex.js` to fix linter crash. +- [x] Created `perf/hits-2026-02-17.json` inventory. diff --git a/docs/agents/task-logs/daily/2026-02-17_06-45-57_perf-agent_completed.md b/docs/agents/task-logs/daily/2026-02-17_06-45-57_perf-agent_completed.md new file mode 100644 index 00000000..4211216c --- /dev/null +++ b/docs/agents/task-logs/daily/2026-02-17_06-45-57_perf-agent_completed.md @@ -0,0 +1,6 @@ +# perf-agent completed + +- Fixed background CPU usage in `js/services/exploreDataService.js`. +- Identified unbounded concurrency in `js/services/relayHealthService.js`. +- Fixed `npm run lint:hex` crash due to large minified file (which was a transient artifact but exposed a buffer limit). +- Generated `daily-perf-report-2026-02-17.md`. diff --git a/js/services/exploreDataService.js b/js/services/exploreDataService.js index 27efcd44..ca8998be 100644 --- a/js/services/exploreDataService.js +++ b/js/services/exploreDataService.js @@ -167,6 +167,11 @@ export default class ExploreDataService { startIntervals() { this.clearIntervals(); + + if (typeof document !== "undefined" && document.hidden) { + return; + } + if (Number.isFinite(this.historyRefreshIntervalMs) && this.historyRefreshIntervalMs > 0) { this.watchHistoryInterval = setInterval(() => { this.refreshWatchHistoryTagCounts({ reason: "interval" }); diff --git a/perf/hits-2026-02-17.json b/perf/hits-2026-02-17.json new file mode 100644 index 00000000..43c83db9 --- /dev/null +++ b/perf/hits-2026-02-17.json @@ -0,0 +1,26 @@ +[ + { + "file": "js/services/exploreDataService.js", + "pattern": "setInterval", + "line": 171, + "trigger": "page load / initialization", + "impact": "Starts background intervals (watch history sync, tag IDF calc) even if tab is hidden.", + "fix": "Check document.hidden inside startIntervals()." + }, + { + "file": "js/services/relayHealthService.js", + "pattern": "Promise.allSettled", + "line": 239, + "trigger": "refresh() called (e.g. periodically or on demand)", + "impact": "Unbounded concurrency for relay checks. If many relays, spawns many connections.", + "fix": "Use a concurrency limit (e.g. p-limit equivalent)." + }, + { + "file": "js/ui/loginModalController.js", + "pattern": "setInterval", + "line": 395, + "trigger": "login modal open", + "impact": "Polls for modal close if MutationObserver fails. Checked document.hidden but context is complex.", + "fix": "Ensure visibility checks are robust." + } +] diff --git a/scripts/check-hex.js b/scripts/check-hex.js index ee1a56b3..ad540e4b 100755 --- a/scripts/check-hex.js +++ b/scripts/check-hex.js @@ -35,7 +35,8 @@ const IGNORED_GLOBS = [ 'releases/**', 'bitvid-working-webtorrent/**', 'scripts/agent/**', - 'docs/capacitor-native-app-plan.md' + 'docs/capacitor-native-app-plan.md', + 'js/webtorrent.min.js' ]; const gitArgs = [ @@ -55,7 +56,9 @@ for (const glob of IGNORED_GLOBS) { // We rely on 'git' being available and 'git grep' supporting -P. // Typically available in most CI/dev environments. -const result = spawnSync('git', gitArgs, { encoding: 'utf8' }); +// Increase maxBuffer to 10MB to avoid ENOBUFS on large outputs. +console.log("Running git with args:", gitArgs.join(" ")); +const result = spawnSync('git', gitArgs, { encoding: 'utf8', maxBuffer: 1024 * 1024 * 10 }); if (result.error) { console.error('Failed to execute git grep:', result.error.message);