Skip to content

perf(stream): Adaptive polling, diagnostics optimization, and lag classification#149

Merged
zortos293 merged 1 commit intodevfrom
capy/adaptive-stream-performance
Mar 19, 2026
Merged

perf(stream): Adaptive polling, diagnostics optimization, and lag classification#149
zortos293 merged 1 commit intodevfrom
capy/adaptive-stream-performance

Conversation

@zortos293
Copy link
Collaborator

@zortos293 zortos293 commented Mar 19, 2026

Summary

Optimizes streaming performance through adaptive input polling, decoupled diagnostics, and real-time lag classification.

Performance Improvements

Adaptive polling

  • Gamepad polling now dynamically adjusts between 4ms (active controllers, visible document) and 100ms (idle or no controllers)
  • Microphone meter uses 33ms timer interval instead of per-frame rAF loop, with reduced analyser FFT size (256)

Decoupled diagnostics

  • Moved stream diagnostics to external store using useSyncExternalStore to eliminate React re-renders from 500ms stats polling
  • StreamView and App subscribe directly to the store instead of props drilling stats through the component tree

Lag classification

  • Added comprehensive lag reason analyzer detecting: network congestion, decoder saturation, input backpressure, and render bottlenecks
  • Classifies signals into reasons: network, decoder, input_backpressure, render, stable, or unknown
  • Surfaces lag reason and detail strings in the in-game stats overlay for actionable feedback

Changes

src/renderer/src/gfn/webrtcClient.ts

  • Added StreamLagReason type and lagReason/lagReasonDetail to StreamDiagnostics
  • Implemented classifyLagReason() for automatic bottleneck detection
  • Converted gamepad polling to adaptive via scheduleGamepadPolling() and getGamepadPollIntervalMs()
  • Integrated lag classification into stats collection loop

src/renderer/src/utils/streamDiagnosticsStore.ts (new)

  • External store for stream diagnostics with createStreamDiagnosticsStore() and useStreamDiagnosticsStore() hook
  • Uses useSyncExternalStore for efficient subscriptions without React re-renders

src/renderer/src/App.tsx

  • Replaced setDiagnostics state with diagnosticsStore external store
  • Removed stats prop from StreamView; components now subscribe directly

src/renderer/src/components/StreamView.tsx

  • Subscribes to diagnostics via useStreamDiagnosticsStore() hook
  • Added lag reason display in stats HUD with color-coded badges
  • Switched microphone meter to 33ms setTimeout loop with reduced FFT size

src/renderer/src/components/StatsOverlay.tsx

  • Added lag reason indicator in overlay for compact diagnostics view

Open in Capy OPE-12 · 5.4 Mini

@zortos293 zortos293 added the capy Generated by capy.ai label Mar 19, 2026 — with Capy AI
@zortos293 zortos293 merged commit 7ae1930 into dev Mar 19, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

capy Generated by capy.ai

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant