Skip to content

perf(browser): throttle idle guests between active operations - #34776

Merged
OrcaWin merged 3 commits into
mainfrom
OrcaWin/electron-browser-idle-throttle
Oct 28, 2026
Merged

OrcaWin merged 3 commits into
mainfrom
OrcaWin/electron-browser-idle-throttle

Conversation

@OrcaWin

@OrcaWin OrcaWin commented Oct 28, 2026 •

Copy link
Copy Markdown
Collaborator
Files Added Deleted Net
Test 7 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​279 $\color{#cf222e}{\Huge{\mathbf{−}}}$​7 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​272
Prod 8 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​76 $\color{#cf222e}{\Huge{\mathbf{−}}}$​25 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​51

ELI5

Idle browser pages keep running their timers after Orca is hidden. Let idle pages rest, and temporarily wake them while a browser command, screenshot or live stream needs them.

What Changed

  • Remove the permanent background-throttling exemption from browsing guests.
  • Reuse the existing publication lease. Every queued command leases only its guest (holdGuestActive) when its queue turn starts, after resolving the current guest. Commands do not take the renderer paint hold, host unthrottle or host re-hide readback; fix(browser): let pixel capture hold its own page drawn, without the desktop window #22534's capture-only paint design stays intact. The full holdPaintForCapture (renderer paint hint, host lease, guest lease) remains on the capture paths only: CDP screenshots, the first-paint gate, selection screenshots and extension tabs.captureVisibleTab.
  • When a guest is unfocused, its release still runs the existing guest re-hide (capturePage with an empty rect and stayHidden) after each command. This is the same mechanism screencasts and captures already use.
  • The one-way browser:capturePaintHold notification never throws (for example, from a disposed frame), so it cannot fail the capture it accompanies.
  • Preserve concurrent capture/stream ownership, guests without a desktop renderer and replacement renderers. Release ownership on success, settled cancellation, setup/capture failure and host-acquire failure.

Why

Measured on Linux with Electron 43.8.1, a hidden native host and one real registered webview running a 16ms interval plus requestAnimationFrame:

Three-second workload Guest timer callbacks Guest rAF callbacks
Original idle attachment policy 188 3
Fixed idle, repeated samples 4 / 5 / 4 0 / 0 / 0
Active capture lease 188 3
After the last capture release 4 0

This removes about 98% of the measured idle timer callbacks. Reusing the existing owner lets concurrent commands, captures and streams keep the page active until the last owner finishes. CPU, RAM, GPU and battery savings were not measured.

Linked Issue

None; found during the Electron reliability and performance audit.

Visual Proof

N/A

The change affects hidden-page scheduling and has no visible UI change. The before/after native callback counts are above. This captured fixture image verifies that hidden screenshots still contain the expected rendered page:

Pixel-verified capture of the hidden native guest

Testing

  • I manually tested these changes locally

  • Automated tests added/updated, or explained why not below

  • ORCA_BACKGROUND_LAUNCH=1 pnpm check:changed --maxWorkers=2: 20 checks passed (835.5s).

  • Targeted runs: 164 bridge/stream/throttle tests; 25 final lease/queue/lifecycle tests; 36 initial manager/grab/extension tests; 12 popup-policy tests; existing native streamed-page destruction test, covering three cycles with a surviving host. Node typecheck passes.

  • Three regression checks fail against unchanged production sources: permanent idle exemption, guest ownership without a renderer and queued command ownership/replacement.

  • Real AgentBrowserBridge evaluation awaits two animation frames and a timer, then returns to idle. HTTP navigation succeeds. A first click after the existing bounded first-paint gate reaches its target on a fresh hidden document.

  • Viewport, full-page and streamed images match expected pixels. Two real runtime stream subscribers plus a simultaneous capture share ownership; leaving one subscriber keeps both contents active, and leaving the last restores idle throttling automatically.

  • Review follow-up: after the switch to guest-only command leases, the native harness was re-run on an isolated hidden Xvfb display. Idle callbacks were 3/3/3 timers per 3s. Agent rAF+timer evaluation, HTTP navigation, the first-paint click, viewport/full-page/stream pixels and automatic restore all passed. Bridge tests assert that non-capture commands never call holdPaintForCapture.

  • Failure/teardown controls cover queued replacement, dropped queued work, killed running work, setup/capture failure, duplicate release, shared/offscreen ownership, renderer replacement/destruction and notification/acquire failures.

Review

Review the queue execution boundary, per-renderer capture accounting and final release paths. Native checks use production managers and capture/stream code in an isolated hidden shell, with CDP screenshot inspection.

Agent skill upstream boundary

  • Not applicable, or this change copies or mechanically translates no upstream skill-installer source, tests, fixtures, registry entries, path tables, comments, or documentation.

Notes

Linux/Xvfb native validation only. CPU/GPU cost of the per-command guest re-hide readback was not measured. Full Orca navigation/focus flows, macOS, Windows, remote live sessions and a physical mobile client were not executed. The code uses platform-neutral Electron APIs and changes no remote/mobile protocol. Hidden Xvfb records no paint-timing entry within the existing first-paint deadline, so the input control asserts actual click delivery.

Checklist

  • This PR is small and focused
  • I explained what changed and why (ELI5, the user-facing before/after, the mechanism, and why over the alternatives)
  • Before/after screenshots or videos attached for UI changes, or N/A with reason
  • Self-reviewed for correctness, security, and performance
  • Cross-platform, SSH/remote, and path/shortcut impact considered (or N/A)
  • pnpm lint, pnpm typecheck, pnpm test, and pnpm build pass (or CI will cover; local preferred)

The changed-file gate result is recorded above; CI will cover the full build/test and platform matrix.

Keep the renderer paint hold, host unthrottle, and host re-hide readback on
capture paths only, and never let the one-way paint-hint send fail the capture.
@OrcaWin
OrcaWin force-pushed the OrcaWin/electron-browser-idle-throttle branch from 3d009e1 to 470abe6 Compare October 28, 2026 08:06
@OrcaWin
OrcaWin marked this pull request as ready for review October 28, 2026 08:26
@coderabbitai

coderabbitai Bot commented Oct 28, 2026

Copy link
Copy Markdown
Contributor

Review in Change Stack →

No actionable comments were generated in the recent review.

Recent review info
Run configuration
  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Repository UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 42a468e4-fbbc-4fc1-a89f-06de7ffa8d71
Commits

Reviewing files that changed from the base of the PR and between 70edd36 and 470abe6.

Files selected for processing: 15
  • src/main/browser/agent-browser-bridge-capture-paint-hold.test.ts
  • src/main/browser/agent-browser-bridge-queue.ts
  • src/main/browser/agent-browser-bridge-session-lifecycle.test.ts
  • src/main/browser/agent-browser-bridge-test-harness.ts
  • src/main/browser/browser-manager-grab-test-harness.ts
  • src/main/browser/browser-manager-grab.ts
  • src/main/browser/browser-manager-guest-lifecycle.test.ts
  • src/main/browser/browser-manager-guest-policy.ts
  • src/main/browser/browser-manager-guest-visibility.test.ts
  • src/main/browser/browser-manager-popup-child.test.ts
  • src/main/browser/browser-manager-popup-routing.test.ts
  • src/main/browser/browser-manager-visibility.ts
  • src/main/browser/extensions/api/tabs-capture.test.ts
  • src/main/browser/extensions/api/tabs-capture.ts
  • src/main/runtime/browser/browser-screencasts.ts
Files with no reviewable changes: 1
  • src/main/browser/browser-manager-guest-policy.ts

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 1 remain after this review.

Walkthrough

The change adds guest activity and paint holds for queued commands and screenshot capture paths. Holds are released after completion or failure. BrowserManagerVisibility coordinates guest publication throttling and renderer paint hints, including overlapping holds and page replacement. Standard browsing guests no longer have background throttling disabled during policy attachment. Tests cover hold acquisition, release, and failure cases.

Priority: Low

Merge Risk: Minimal · up to 470ab

No identified defect blocks merging; the guest and capture holds have documented release paths.

Pre-merge checks: Passed 4 · Failed 1

Failed Failed checks: 1 warning

Check name Status Explanation Resolution
Docstring Coverage Warning Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff with cyclomatic complexity of at least 2. Documenta… Write docstrings for the functions missing them to satisfy the coverage threshold.
Passed Passed checks: 4 passed
Check name Status Explanation
Title check Passed The title "perf(browser): throttle idle guests between active operations" matches the main change: browsing guests now throttle when idle and are temporarily held active for commands, captures, and st…
Description check Passed The description follows the repository template. It includes ELI5, What Changed, Why (with measurements and reasoning), Visual Proof (N/A with reason and a fixture image), Testing with commands and re…
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Full details: Title check

Explanation

The title "perf(browser): throttle idle guests between active operations" matches the main change: browsing guests now throttle when idle and are temporarily held active for commands, captures, and streams. It is specific, uses a conventional commit prefix, and avoids vague wording. The title does not mention the capture-only paint hold or the queue-level lease, but it does not need to cover every detail.

Full details: Description check

Explanation

The description follows the repository template. It includes ELI5, What Changed, Why (with measurements and reasoning), Visual Proof (N/A with reason and a fixture image), Testing with commands and results, Review, Agent skill upstream boundary, Notes, and Checklist. Two gaps exist. The Linked Issue section says 'None' and has no 'Fixes #' reference, which the template says is required for outside contributors. The AI Disclosure section is missing, although the template says it is only skipped for StablyAI team members and the author's status is not stated. The final checklist item for pnpm lint/typecheck/test/build is unchecked, with a note that CI will cover it.

Resolution

Consider these additions before merge: link an existing issue in the Linked Issue section (the template states that outside contributors need one, and 'None' does not meet this), or confirm that the author is a StablyAI team member. Fill in the AI Disclosure section if AI tools were used. Confirm the status of the unchecked lint/typecheck/test/build item.

Full details: Docstring Coverage

Explanation

Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff with cyclomatic complexity of at least 2. Documentation-only edits and deletions within surviving functions are included; unchanged diff context and fully deleted functions are excluded. Analyzed 3 functions across 14 files.

Resolution

Write docstrings for the functions missing them to satisfy the coverage threshold.

Finishing Touches: 💡 1
📝 Generate docstrings: 💡
  • Commit to this branch
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@OrcaWin
OrcaWin merged commit 9c76546 into main Oct 28, 2026
82 of 84 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant