Skip to content

fix(frontend): prevent replay capture from freezing maps - #572

Merged
JesJehle merged 1 commit into
mainfrom
fix/posthog-map-canvas-recording
Sep 2, 2026
Merged

fix(frontend): prevent replay capture from freezing maps#572
JesJehle merged 1 commit into
mainfrom
fix/posthog-map-canvas-recording

Conversation

@JesJehle

@JesJehle JesJehle commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

Briefing

PostHog replay canvas capture was synchronously reading every OpenLayers canvas several times per second, which caused repeated main-thread stalls while users panned or zoomed maps. This change keeps useful map imagery in session replays while replacing continuous capture with bounded settled and periodic frames across the normal DeadTrees and PRIWA maps. Non-map canvases are excluded so camera-backed and processing canvases cannot enter replay.

What changed

  • Limit eligible map frames to 1 FPS, 50% linear resolution, and 0.3 encoding quality.
  • Suppress map canvas reads during pointer and wheel interaction, then capture one settled frame after the interaction burst.
  • Refresh a newly loaded map after 5 seconds and then every 30 seconds so asynchronous tile, layer, and programmatic changes do not leave replay stale.
  • Fail closed for every canvas outside an OpenLayers viewport, including the hidden QR scanner canvas.

Validation

  • npm --prefix frontend test: 66 files, 329 tests passed.
  • npm --prefix frontend run lint: passed.
  • npm --prefix frontend run build: passed.
  • scripts/lint-ast-grep.sh: passed.
  • Prod-connected local normal map baseline, 60 sustained gestures: 549 canvas reads, 3 long tasks, 158 ms maximum frame gap.
  • Same normal map with canvas recording disabled: 0 canvas reads, 0 long tasks, 48 ms maximum frame gap.
  • Final PRIWA mobile-sized run, 10 sustained gestures: 0 canvas reads during interaction, 1 settled 197x426 frame afterward, 0 later idle reads in the observation window, 0 long tasks, and 0 frame gaps above 20 ms.
  • Production PostHog diagnostic, last 14 days: 57 map sessions had replay snapshot stalls of at least 500 ms across mobile and desktop traffic.
  • Thermonuclear review completed with no remaining P1; Codex autoreview ran twice and both accepted P1 findings were fixed and locally verified.

Risk and limitations

Map replay imagery is intentionally lower fidelity and temporally sparse. Non-map canvases are no longer recorded; ordinary DOM replay, pointer activity, and analytics events remain available. A bounded map refresh can still do one canvas read after interaction settles, but continuous capture during active panning is removed.

Reviewer guide

Please focus on the maskRegionsFn contract: null skips a frame, while [] permits only an explicitly selected OpenLayers map frame.

@JesJehle JesJehle added the frontend Frontend changes label Sep 2, 2026
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 2, 2026

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review Completed 2026-09-02T08:29:35.108359Z 4d27aea PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@github-actions

github-actions Bot commented Sep 2, 2026

Copy link
Copy Markdown

Frontend preview

Open Firebase preview

Channel: pr572-fix-posthog-map-canvas-r
Commit: 4d27aea1aa18a376ed70fb7f01b3d83a42ffe06f

@JesJehle
JesJehle merged commit c261027 into main Sep 2, 2026
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

frontend Frontend changes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant