G/V-Lag: 1-s-Fallback + ehrlicher Verbindungspunkt (v=151)

Zuerst gemessen, dann gedreht - und das Backend war NICHT das Problem:
  /api/snapshot   75 Abrufe in 20 s -> 21 verschiedene ts = ~1/s
  WebSocket-Push  direkt am Socket gemessen: Median 1,04 s (min 1,00 max 1,06)
  G/V-Aenderungen Ø 1,44 s - das ist der Markt, keine Verzoegerung

Die ganze Server-Kette liefert bereits 1 s. Der Lag entsteht erst am Handy:
bricht der WebSocket STILL weg (WireGuard-Aussetzer, App-Wechsel), traegt nur
noch der REST-Poll - und der stand auf 4 s.

POLL_MS 4000 -> 1000, aber mit Sperre: solange der WS liefert (lastWsMs,
Fenster WS_FRISCH_MS=2200 ms), ueberspringt der Poll den Abruf. Kein
zusaetzlicher Verkehr im Normalfall.

Denkfehler, den erst die Simulation zeigte: der erste Entwurf las die
WS-Frische aus lastRecvMs (jede Quelle) - damit drosselte sich der Poll SELBST
und kam bei totem WS nur auf 2,9 s statt 1 s. Jetzt zwei getrennte Uhren.

Simuliert: WS gesund -> 0 Zusatz-Abrufe, max. Alter 0,9 s. WS tot -> 1/s, max.
Alter 0,9 s. WS traege (5 s) -> max. 2,9 s. Vorher bei totem WS: 4,0 s.

Der Verbindungspunkt log: er wurde nur bei sock.onclose auf "off" gesetzt, aber
genau der Fall, der den Lag erzeugt, feuert KEIN onclose - der Socket haengt
still, der Punkt blieb gruen. Neu .dot.stale (bernstein, pulsierend) ab 3,5 s
ohne frischen Snapshot: gemessen wird, was ANKOMMT, nicht was der Socket ueber
sich behauptet.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Axel Hocks
2026-08-07 14:20:42 +02:00
co-authored by Claude Opus 5
parent c445c687f5
commit 59e9498237
4 changed files with 87 additions and 4 deletions
+7
View File
@@ -45,6 +45,13 @@ header{
.dot{width:11px;height:11px;border-radius:50%;display:inline-block}
.dot.on{background:var(--up);box-shadow:0 0 8px var(--up)}
.dot.off{background:var(--down);box-shadow:0 0 8px var(--down)}
/* stale = der Socket behauptet Verbindung, liefert aber nichts mehr (2026-08-07).
Bernstein + Pulsieren, damit der Unterschied zu „verbunden" auf einen Blick
sichtbar ist — genau dieser Zustand erzeugte den G/V-Lag. Schlägt `.on` und
`.off`, deshalb hier NACH beiden. */
.dot.stale{background:var(--warn,#f0a020);box-shadow:0 0 8px var(--warn,#f0a020);
animation:dotpuls 1.2s ease-in-out infinite}
@keyframes dotpuls{0%,100%{opacity:1}50%{opacity:.35}}
.price-row{display:flex;flex-wrap:wrap;gap:8px;margin-top:10px}
/* flex-basis 28% → 3 Boxen je Reihe, die 5. Box (KURS/G/V) bricht sauber um */
.px{flex:1 1 28%;background:var(--card);border:1px solid var(--border);