Fix map drift on tab return, speed cold start, mark OpenSky tracks#107
Merged
Conversation
Map animation / perf and multi-source fallback improvements: - Fix aircraft "drift away then snap back" after the browser tab is backgrounded. The rAF loop pauses while hidden but the WebSocket keeps delivering updates, so on return PVB extrapolated each track forward by the entire away-window. Add a visibilitychange handler that re-anchors motion smoothing to current server truth on resume, clamp the pulse dt, and add a hard MAX_PROJECT_MS ceiling on extrapolation as a backstop. - Speed up cold start with a REST prefetch of /entities so the map renders immediately instead of waiting for the WS handshake + first poller snapshot. Guarded on an empty store so it never clobbers live WS data. - Visually mark OpenSky-supplemented aircraft (dimmed icon) so it is clear when a track is lower-fidelity gap-fill rather than the local BEAST feed. - Document the recommended authenticated OpenSky setup for smooth ~30s Beast-gap handover in .env.example.
- Eliminate the icon "jiggle/swim" during pan & zoom. The standalone Deck instance on a separate canvas was synced to MapLibre by pushing viewState every rAF, leaving the two canvases a frame out of phase. Replace it with @deck.gl/mapbox MapboxOverlay added as a map control, so Deck renders in lockstep with the base map's render loop. Removes the per-frame viewState push and manual canvas resize; preserves the deck-overlay-canvas id so the snapshot export keeps working, and routes picking through overlay.pickObject. - Memoize static / slow-changing layer groups (custom, geofence, observation rings, mesh, stream gauges, cameras, annotations) so they rebuild only when their inputs change instead of on every animation frame. Reused Layer instances let deck.gl skip re-diffing them; only the PVB/pulse-animated entity, trail, event and lightning layers rebuild each frame. - Enable the OpenSky supplement by default with a 30s cadence and 25s gap handover (assumes a free OpenSky account, which most users register). Anonymous users are advised to raise the interval or disable it.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Addresses map performance, the "icons drift away then catch up" behavior after switching tabs, and smoother multi-source ADS-B fallback (Beast → OpenSky).
1. Drift-on-tab-return (root cause fix)
The motion system (Projective Velocity Blending,
pvb.ts) extrapolates each aircraft forward from its last server report by wall-clock elapsed time. The rAF loop inMapOverlay.tsxusedDate.now()with no clamp and no Page Visibility handling. When a tab is backgrounded the browser pauses/throttlesrequestAnimationFramewhile the WebSocket keeps delivering updates — so on return, every plane got projected forward by the entire away-window (the drift), then snapped to truth (the catch-up).visibilitychangehandler that re-anchors PVB to current server positions on resume (clears stale anchors soapplyPVBre-seeds at reported position).dtso a throttled rAF can't fast-forward the animation phase.MAX_PROJECT_MS(30s) ceiling on extrapolation as a backstop for any large gap (WS reconnects, etc.). Set above the widest blend window so normal motion is never clipped.2. Slow loading
Initial map state previously arrived only after the WS handshake and the poller's first snapshot tick (up to a few seconds). Added a REST prefetch of
/entitiesinuseWebSocket.tsso the map renders immediately. Guarded on an empty store so it never clobbers live WS data that may have already arrived.3. Beast → OpenSky fallback (fast handover + visual marker)
The multi-source supplement machinery already exists in
poller/pollers/adsb.py(prioritybeast > ultrafeeder > opensky, gap-fill via holdoff window). This PR makes the fast + visual marker behavior the user requested:buildEntityLayers.ts) so it's clear a track is lower-fidelity gap-fill rather than the local BEAST feed. The frontend already re-anchors PVB cleanly on source flips, so handover is smooth..env.example(interval 30s → ~30s gap handover), with the effective-handover-window formula and rate-limit guidance.Testing
npx tsc --noEmitpasses..env.exampleis documentation only.Notes
https://claude.ai/code/session_01HS4mM3wZUW76r7PLHcwHFV
Generated by Claude Code