8000 Rasterise remaining static card SVGs; cut Android UseView draw jank by gasnet-supervisor[bot] · Pull Request #166 · gassius/lateralzr · GitHub
[go: up one dir, main page]

Skip to content

Rasterise remaining static card SVGs; cut Android UseView draw jank - #166

Closed
gasnet-supervisor[bot] wants to merge 3 commits into
mainfrom
cursor/lz-android-remaining-svg-raster-d81a
Closed

gasnet-supervisor[bot] wants to merge 3 commits into
mainfrom
cursor/lz-android-remaining-svg-raster-d81a

Conversation

@gasnet-supervisor
Copy link
Copy Markdown
Contributor

Agent-Ticket: 1amjtrex6xz (https://app.clickup.com/t/1amjtrex6xz)

Perfetto on Galaxy A50 (main after #163/#164) showed ~86% of janky-frame time in UI-thread software draw of remaining react-native-svg nodes.

  • Reuse Rasterise PatternLayer once to a cached Image (cut SVG UseViews) #164 raster path for NoMediaEmboss + LoadingCard; Reanimated transforms on parents so SVG subtree never re-invalidates.
  • Pre-mount current card + 2 after settle; back emboss captured unflipped.
  • Prefetch current + next 1-2 images at display width.
  • No animation/UX changes; native-first (web same path).

Device verification pending: Hermes 10 swipes + 5 flips on A50 vs main (E: 33.46% janky, p99 1150 ms) plus visual parity screenshots.

Reuse PatternLayer's RasterizedSvgXml path for no-media emboss and
LoadingCard so UseView/LineView software-draw leaves the UI thread after
settle. Pre-mount card+2 off-screen once idle, keep Reanimated on parents,
prefetch current+next 1–2 media at display width, and harden E2E raster
settle against concurrent captures.

Agent: GasNet Implementer
Agent-Ticket: 1amjtrex6xz
Agent-Run: https://cursor.com/agents/bc-390d3a06-c4ad-5631-96fb-4ebcb76dd81a
Co-authored-by: gassius <gassius@users.noreply.github.com>
Co-authored-by: cgonzalezr <cgonzalezr@gmail.com>
@vercel
vercel Bot commented Nov 2, 2026 •
Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
lateralzr-client Ready Ready Preview Nov 2, 2026 12:25pm UTC

@github-actions
github-actions Bot commented Nov 2, 2026 •
Copy link
Copy Markdown

Agent: GasNet Implementer

Client E2E screenshots (deterministic Expo web export)

Baseline diff summary (report-only)

Screen % changed Result Diff
card-back_no-description_390x844_en.png 1.45% over-threshold diff
card-back_no-media_390x844_en.png 0.00% pass —
card-back_no-media-200_390x844_en.png 0.54% pass —
card-back_with-diagram_390x844_en.png 0.00% pass —
card-back_with-photo_390x844_en.png 0.00% pass —
card-back_with-photo-200_390x844_en.png 0.00% pass —
card-back_with-photo-200-scrolled_390x844_en.png 0.00% pass —
card-back_with-transparent_390x844_en.png 0.00% pass —
card-front_collective-intelligence_390x844_en.png 0.00% pass —
card-front_intergenerational_390x844_en.png 0.00% pass —
card-front_long-label_390x844_en.png 0.00% pass —
card-front_short-label_390x844_en.png 0.00% pass —
card-front_tide_390x844_en.png 0.00% pass —
status_fetch-failed_390x844_en.png 0.00% pass —
status_loading_390x844_en.png 0.14% pass —
status_loading-200_390x844_en.png 0.19% pass —
status_loading-initial_390x844_en.png 0.14% pass —
status_neighbourhood-loading_390x844_en.png 0.30% pass —
status_no-next-idea_390x844_en.png 0.00% pass —
status_offline_390x844_en.png 0.00% pass —

@gasnet-pr-reviewer gasnet-pr-reviewer Bot left a comment
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agent: Pull Request Reviewer

Verdict: Approve

Blockers: none.

Minors (in-PR, actionable):

  • M1 apps/client/components/ConceptCardStack.tsx:1494-1515 — the prewarm slot mounts a full ConceptCardForIndex (media + pattern + emboss raster) for card+2. It is bounded to one card and unmounts while dragging. Still, before you leave draft, include the pending A50 Perfetto run (10 swipes + 5 flips vs main) in the PR body so we can confirm the extra idle mount does not add memory pressure or late-commit jank on low-end Android. The PR body says this device check is still pending.
  • M2 apps/client/e2e/helpers/patternRender.ts (poll body, diff hunk @@-98) — the checks are just as strict: size, non-blank and optional glow are still required on the same settled PNG. But the old expect(...) messages that gave expected vs actual size, opaquePixels and glowPixels were lost. Add expected.width x expected.height and the pixel counts to the returned poll strings (e.g. size-${w}x${h}-vs-${ew}x${eh}, blank-${opaquePixels}) so CI failures can still be diagnosed.

CI: all required checks green on a62cfe8 (Client (Expo), API (Laravel), Client E2E gate, Client E2E screenshots 4m12s, Workflow lint, Prod storage binds, VPS Python 3.6, Vercel). Full-screenshot and baseline jobs were skipped.

Evidence:

  • Native-first: NoMediaEmboss and LoadingCard now use the shared RasterizedSvgXml path, which runs the same way on all platforms. The only web-specific code is the existing aria-hidden spread pattern. The intro logo and all other user-facing features are untouched, and animations are unchanged (the prewarm slot is opacity:0, translated off-screen, pointerEvents="none", and hidden from a11y).
  • Prewarm is bounded: only currentIndex+2, gated on patternCaptureEnabled plus a 32 ms armed tick (ConceptCardStack.tsx:979-993). It is torn down during gestures.
  • The cache is bounded: lib/patternBitmapCache.ts:10-11, 24 MB / 24 entries with LRU eviction at :77-85.
  • Prefetch: the hot-path effect fetches at most 3 URLs (MEDIA_PREFETCH_AHEAD=2), deduplicated and covered by a unit test. The deck-wide batch stays debounced.
  • E2E: the settle check and PNG analysis now run in the same poll tick, which removes a remount race without dropping any check. No sudo in any script.

Keep the atomic settle+PNG poll, but surface expected-vs-actual size and
opaque/glow pixel counts again when the poll or post-settle assert fails.

Agent: GasNet Implementer
Agent-Ticket: 1amjtrex6xz
Agent-Run: https://cursor.com/agents/bc-390d3a06-c4ad-5631-96fb-4ebcb76dd81a
Co-authored-by: gassius <gassius@users.noreply.github.com>
Co-authored-by: cgonzalezr <cgonzalezr@gmail.com>
@gasnet-pr-reviewer gasnet-pr-reviewer Bot left a comment
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agent: Pull Request Reviewer

Verdict: Approve

Delta a62cfe8...a13a4b1 (1 commit, fast-forward; only apps/client/e2e/helpers/patternRender.ts).

Blockers: none.

Minors (in-PR):

  • M2 fixed: poll returns now carry expected-vs-actual size (L134), opaquePixels (L138), glowPixels (L142). Post-poll re-asserts sizeOk/nonBlank/hasGlow with the same messages (L156-180). Checks are equally strict or stricter: the same predicates run, plus a re-check after the poll. No web-only paths, no sudo, no UX change (test helper only).
  • M1 is still open: the A50 Perfetto run is pending. Supervisor will plan it before the PR leaves draft.

CI: all checks green on a13a4b1 (API, Client Expo, Client E2E screenshots 4m59s, gate, workflow lint, VPS Py3.6, prod binds, Vercel). Full screenshots and baselines were skipped.

A50 Hermes vs main 17293e4 showed higher janky% / p99 and +PSS from the
fourth ConceptCard tree and eager next-2 Image.prefetch. Keep settle-gated
NoMediaEmboss and LoadingCard rasters (UseView→Image) and restore current-
only immediate media preload.

Agent: GasNet Implementer
Agent-Ticket: 1amjtrex6xz
Agent-Run: https://cursor.com/agents/bc-390d3a06-c4ad-5631-96fb-4ebcb76dd81a
Co-authored-by: gassius <gassius@users.noreply.github.com>
Co-authored-by: cgonzalezr <cgonzalezr@gmail.com>
@gasnet-supervisor
Copy link
Copy Markdown
Contributor Author

Closing: A50 3-run medians show no gain vs main (jank 34.16% vs 34.75%, p99 2500 vs 1650 ms, ~+70 MB PSS). Card rendering is being redone without runtime SVG.

@gasnet-supervisor gasnet-supervisor Bot closed this Nov 2, 2026
github-actions Bot added a commit that referenced this pull request Nov 2, 2026
cursor Bot pushed a commit that referenced this pull request Nov 2, 2026
B1: bake fronts with default title-clear motifs hidden; runtime covers
extra measured-title motif AABBs (no solid rect cut).
B2: restore connector glow via baked soft WebP sprites; endR from
geometry without re-capping node size.
B3: E2E asserts natural size == PATTERN_BAKE_PIXEL (1074×1680) and no SVG.
B4: re-bake -3x.webp + manifest; CI assert-pattern-baked re-bake diff.
Minors: color.paper via hexToRgba; drop #164/#166 RasterizedSvgXml stack
and patternCaptureEnabled; shrink assets to WebP.

Agent: GasNet Implementer
Agent-Ticket: 1amjtrex6xz
Agent-Run: https://cursor.com/agents/bc-390d3a06-c4ad-5631-96fb-4ebcb76dd81a
Co-authored-by: gassius <gassius@users.noreply.github.com>
Co-authored-by: cgonzalezr <cgonzalezr@gmail.com>
gasnet-supervisor Bot added a commit that referenced this pull request Nov 2, 2026
* Replace card SVG with build-time pattern PNGs

Zero react-native-svg on the deck path: bake front/emboss PNGs at 3× from
the pattern SVG masters, show via Image, clear the title with an orange
cover, and drive connector glow with View layers + Reanimated opacity.
Media fade uses expo-linear-gradient. No pre-mount/prefetch; same path on
web preview.

Agent: GasNet Implementer
Agent-Ticket: 1amjtrex6xz
Agent-Run: https://cursor.com/agents/bc-390d3a06-c4ad-5631-96fb-4ebcb76dd81a
Co-authored-by: gassius <gassius@users.noreply.github.com>
Co-authored-by: cgonzalezr <cgonzalezr@gmail.com>

* Fix #167 review: bake clear, soft glow, real E2E size

B1: bake fronts with default title-clear motifs hidden; runtime covers
extra measured-title motif AABBs (no solid rect cut).
B2: restore connector glow via baked soft WebP sprites; endR from
geometry without re-capping node size.
B3: E2E asserts natural size == PATTERN_BAKE_PIXEL (1074×1680) and no SVG.
B4: re-bake -3x.webp + manifest; CI assert-pattern-baked re-bake diff.
Minors: color.paper via hexToRgba; drop #164/#166 RasterizedSvgXml stack
and patternCaptureEnabled; shrink assets to WebP.

Agent: GasNet Implementer
Agent-Ticket: 1amjtrex6xz
Agent-Run: https://cursor.com/agents/bc-390d3a06-c4ad-5631-96fb-4ebcb76dd81a
Co-authored-by: gassius <gassius@users.noreply.github.com>
Co-authored-by: cgonzalezr <cgonzalezr@gmail.com>

* Size baked pattern Image to card face points

Art-director B1: absoluteFill let the 1074×1680 WebP lay out at asset
pixels (~3× crop). Size expo-image to faceWidth×faceHeight with
contentFit cover so one bake fills the face. Glow maps through
xMidYMid slice (same as former SvgXml). decodeFormat rgb + display-sized
style so Android does not keep a full 3× bitmap for a ~358pt face.
LoadingCard uses the same sizing.

Agent: GasNet Implementer
Agent-Ticket: 1amjtrex6xz
Agent-Run: https://cursor.com/agents/bc-390d3a06-c4ad-5631-96fb-4ebcb76dd81a
Co-authored-by: gassius <gassius@users.noreply.github.com>
Co-authored-by: cgonzalezr <cgonzalezr@gmail.com>

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: gassius <gassius@users.noreply.github.com>
Co-authored-by: cgonzalezr <cgonzalezr@gmail.com>

This branch was successfully deployed

1 active deployment
Preview — 6caedb75 Deployed Nov 2, 2026 by vercel[bot]
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

0