Skip to content

perf(stream-stats): throttle the stats tick when the tab is hidden - #998

Open
Endymi0n74 wants to merge 1 commit into
redphx:typescriptfrom
Endymi0n74:feat/streamstats-hidden-throttle
Open

perf(stream-stats): throttle the stats tick when the tab is hidden#998
Endymi0n74 wants to merge 1 commit into
redphx:typescriptfrom
Endymi0n74:feat/streamstats-hidden-throttle

Conversation

@Endymi0n74

Copy link
Copy Markdown

Quoi

La barre de stats (StreamStats) appelle getStats() toutes les secondes même quand l'onglet est caché — inutile (rien de visible à rafraîchir) mais le coût CPU/batterie reste là. Trois changements dans un seul fichier (stream-stats.ts) :

  1. Throttle document.hidden : le tick passe de REFRESH_INTERVAL (1 s, onglet visible) à StreamStatsCollector.INTERVAL_BACKGROUND (60 s, onglet caché) via getInterval().
  2. setIntervalsetTimeout auto-réarmé : l'intervalle est réévalué à chaque tick (le réarmement se fait en fin d'update, pas une fois au start) → au retour au premier plan, la cadence 1 s reprend immédiatement.
  3. Refresh immédiat au retour : un listener visibilitychange déclenche une mise à jour dès que l'onglet redevient visible (pas d'attente du prochain tick).

Au passage, update() est protégé contre la réentrance (isUpdating flag + try/finally) : collect() est async, un getStats() lent ne peut plus chevaucher le tick suivant.

Pourquoi c'est sûr

  • Aucun changement quand l'onglet est visible : cadence 1 s identique, mêmes valeurs, même rendu.
  • Le flag isUpdating ne change que le timing de la boucle — collect()/getStat()/rendu intacts.
  • La constante INTERVAL_BACKGROUND = 60 * 1000 existait déjà dans StreamStatsCollector (inutilisée) — le patch la branche, zéro nouvelle valeur magique.
  • Le listener visibilitychange est ajouté dans le constructeur, aucun retrait nécessaire (la classe est un singleton de session).

Détails

  • 1 fichier : src/modules/stream/stream-stats.ts (+45/−21)
  • Build : bun build.ts --version 6.7.12 --variant full → exit 0 (gate eslint + TS)
  • Mesure (fork) : la barre de stats 1 s en arrière-plan coûtait un getStats() complet par seconde ; passé à 1/60 s quand l'onglet est caché — le gain dépend du temps de collect() (report RTC de ~50 entrées ≈ µs), mais supprime 59/60 des appels getStats() sur un stream en arrière-plan (lecture prolongée + autre onglet actif, scénario courant).

When the document is hidden the stats bar kept polling getStats() every
second for no visible benefit. The tick now switches to
INTERVAL_BACKGROUND (60 s) via a self-rearming setTimeout — the interval
is re-evaluated on every tick (document.hidden), so stats refresh
immediately when the tab becomes visible again (visibilitychange listener
triggers one update right away).

The update() is also guarded against re-entrancy (isUpdating flag with
try/finally), which matters now that collect() is async: a slow getStats()
call can no longer overlap the next tick.

Single file, no behaviour change while the tab is visible (still 1 s).

🤖 Generated with Codebuff
Co-Authored-By: Codebuff <noreply@codebuff.com>
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