Skip to content

Reduce first-paint compositing to prevent iOS-26 WKWebView render freeze #222

@jasoneplumb

Description

@jasoneplumb

Context

The blank-on-cold-start is a whole-page compositing freeze in iOS-26 WKWebView (Edge/Chrome on iOS); Safari works (system WebKit handles the compositing; WKWebView is more sensitive to first-paint compositing-layer pressure). JS can't detect a compositing freeze (paint is recorded — FCP fires — but never composited to screen), so the Paint-Timing auto-reload (#221) doesn't fire. Pivot from recover to prevent: reduce what gets composited at first paint.

What composites before any JS runs (the freeze is at the consent gate, pre-initApp)

  • #map { isolation: isolate } — a full-screen composited layer present from first paint (empty until the map inits).
  • static #offline-bannerposition: fixed + transform: translateY(-100%) → a composited (off-screen) layer.

Changes (aggressive: strip all first-paint compositing)

  • style.css: remove isolation: isolate from #map. Safe: it only contained the hillshade overlay's mix-blend-mode: multiply, which blends against the opaque base tiles beneath it regardless (multiply against the white body behind a full-screen map is a no-op).
  • index.html / main.ts: remove the static #offline-banner from the HTML and lazy-create it in updateOfflineBanner() only when actually offline — so it's not in the DOM at first paint.

If this stops the freeze, we've confirmed first-paint compositing pressure was the trigger and can re-introduce containment more surgically if needed. Refs #220, #218.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions