Lesson 233: Spline Embed LCP Fest Landing Receipt on BUILD_RECEIPT (2026)

Direct answer: Before spring fest landing URLs swap, file spline_lcp_fest_receipt_v1.json proving poster-first or click-to-load defer policy, LCP ≤ 2.5 s on mobile throttle lab, zero long tasks overlapping the primary CTA, and a CrUX spot row archived—then promote BUILD_RECEIPT spline_lcp_fest. Distinct from Spline LCP preflight (ninety-second checklist) and R3F self-host preflight (licensing lane).

Lesson hero for Spline embed LCP fest landing receipt

Why this matters now (May 2027 fest landing traffic spike)

May 2027 teams ship CJK store copy and drop a Spline hero iframe above the fold on the fest hubLighthouse mobile LCP 6.2 s, INP red, and Steam in-client browser users never reach the itch demo link. Marketing blames “Spline slow”; the fix is documented embed budget, defer/interaction policy, and a receipt before BUILD_RECEIPT promotion.

The Spline embed LCP preflight is the budget checklist; fest traffic spike preflight is the fest-week URL-swap gate—this lesson is the BUILD_RECEIPT milestone with CI gate verify_spline_lcp_fest_v1.

Beginner path (landing lab smoke)

Step Action Success check
1 Write docs/spline-embed-budget.md row Four budget lines filled
2 Apply poster-first or click-to-load No autoplay iframe in first viewport
3 Run Lighthouse mobile (lab) LCP ≤ 2.5 s
4 Reserve min-height on iframe container CLS stable
5 Click primary CTA twice Second click not worse
6 File spline_lcp_fest_receipt_v1.json lcp_fest_pass: true
7 BUILD_RECEIPT row spline_lcp_fest GREEN

Time: ~70 minutes first fest URL; ~20 minutes when defer policy is pinned.

Developer path (gates L1–L6)

Gate Check Fail when
L1 Embed budget row in git Undocumented iframe URL
L2 Defer / interaction policy Autoplay hero iframe above fold
L3 Single WebGL hero (Rule A) Spline + Phaser/Three on first paint
L4 Lab LCP + long-task spot LCP > 2.5 s or long task on CTA
L5 CrUX spot row archived Lab-only green, no field snapshot
L6 spline_lcp_fest_receipt_v1 + BUILD_RECEIPT Fest URL promoted without receipt

L1 — Embed budget table (copy into receipt)

Budget line Measured Green band
Iframe weight (above fold) ___ KB < 800 KB before first paint
GPU memory class mid-tier phone One diorama, not two scenes
Time to interactive embed ___ s @ 4× CPU < 2.5 s if hero
Long tasks > 50 ms (first 5 s) count 0 overlapping CTA handler

L2 — Defer / interaction policy (pin in #fest-landing-spline)

Policy A — poster-first (recommended for Steam links):

<div class="spline-hero" style="min-height: 480px; position: relative;">
  <img src="/assets/fest-hero-poster.webp" width="960" height="480"
       alt="Fest hero still" fetchpriority="high" />
  <button type="button" id="load-spline-embed">View 3D scene</button>
  <iframe id="spline-embed" hidden loading="lazy"
    data-src="https://my.spline.design/SCENE_ID"
    title="Fest diorama"></iframe>
</div>
document.getElementById('load-spline-embed')?.addEventListener('click', () => {
  const iframe = document.getElementById('spline-embed');
  iframe.src = iframe.dataset.src;
  iframe.hidden = false;
});

Policy B — click-to-load only: iframe src empty until gesture; poster is LCP element.

Fail closed on autoplay orbit timers in first viewport.

L4 — Lighthouse lab capture

  1. Chrome DevTools → Lighthouse → Mobile → Performance.
  2. Throttle: 4× CPU, Slow 4G (or team preset).
  3. Archive release-evidence/03-web/lighthouse-fest-landing-mobile.json.
  4. Extract largest-contentful-paint and long-task count into receipt.

L5 — CrUX spot row (field snapshot)

From PageSpeed Insights or Search Console CrUX export:

Metric Spot value Pass band
LCP (p75) ___ s 2.5 s (or team waiver documented)
INP (p75) ___ ms 200 ms
CLS (p75) ___ 0.1

Note: Field data lags deploy—file lab L4 even when CrUX is “N/A”; refresh CrUX row after 28 days if fest runs long.

spline_lcp_fest_receipt_v1.json

{
  "schema": "spline_lcp_fest_receipt_v1",
  "build_label": "spring-fest-2027-rc1",
  "landing_url": "https://example.com/fest-hub",
  "spline_scene_id": "SCENE_ID",
  "embed_policy": "poster_first_click_to_load",
  "budget": {
    "iframe_kb_above_fold": 620,
    "long_tasks_gt_50ms_first_5s": 0,
    "lab_lcp_seconds_mobile": 2.1
  },
  "crux_spot": {
    "lcp_p75_seconds": 2.4,
    "inp_p75_ms": 180,
    "cls_p75": 0.05,
    "source": "pagespeed_insights",
    "captured_at_utc": "2027-05-12T18:00:00Z"
  },
  "paired_receipts": {
    "store_copy_cjk": "release-evidence/02-store/copy/STORE_COPY_CJK_RECEIPT.json"
  },
  "gates": {
    "L1_embed_budget": "pass",
    "L2_defer_policy": "pass",
    "L3_single_webgl_hero": "pass",
    "L4_lab_lcp": "pass",
    "L5_crux_spot": "pass",
    "L6_build_receipt": "pass"
  },
  "lcp_fest_pass": true,
  "fest_promotion_allowed": true
}

Pin under release-evidence/03-web/SPLINE_LCP_FEST_RECEIPT.json.

BUILD_RECEIPT row (L6)

Column Pass when
spline_lcp_fest Receipt path + lcp_fest_pass: true
store_copy_cjk Lesson 232 independent
html5_channel_label Lesson 201 for itch embed lane

Relationship to guide vs self-host

Artifact Role
Spline LCP preflight L1–L4 checklist
Fest traffic spike preflight Fest-week URL swap + defer under load
R3F handoff preflight Self-host when iframe budget fails
This lesson BUILD_RECEIPT spline_lcp_fest + CrUX spot

Key takeaways

  1. Fest traffic hits marketing URLs first—not your game binary.
  2. Poster-first keeps LCP on still + CTA, not WebGL iframe.
  3. Rule A: one WebGL hero per viewport.
  4. Pair with 232—store copy and landing ship same week.
  5. Steam in-client browser ≈ Deck memory pressure for embed policy.
  6. Archive lab + CrUX spot—do not claim field green from desktop only.
  7. Wednesday demo smoke should include landing URL row.
  8. Q2 capstone 235 wires 233 with 230–234.
  9. July playtest concurrent load: Lesson 252spline_playtest_lcp_spot_receipt (cousin column, not fest JSON).

Common mistakes

  • Measuring desktop only during mobile fest skew.
  • Two WebGL heroes (Spline + auto-start Phaser).
  • CMS stripping loading="lazy"—verify View Source.
  • Promoting fest URL without min-height → CLS fails CTA.
  • Confusing CrUX N/A with permission to skip defer policy.

Troubleshooting

Symptom Lane
LCP 4–8 s mobile L2 poster-first; shrink Spline scene
CTA frozen on first click L4 long tasks—defer embed
Layout jump on load min-height + poster dimensions
Steam Deck tab reload L3 remove second WebGL context
Lab green, CrUX red Wait for field; tighten L2 further

Mini exercise (65 minutes)

  1. Break L2 on purpose (autoplay iframe)—confirm L4 fails.
  2. Enable poster-first; pass lab LCP.
  3. File receipt with crux_spot row (or N/A + waiver note).
  4. Link 232 receipt in paired_receipts.
  5. Set BUILD_RECEIPT spline_lcp_fest GREEN.

Continuity — Q2 2027 spring fest shipping (230–235)

Lesson Receipt focus
230–232 Art, audio, store copy
233 (this) Spline fest landing LCP
234 Micro-trailer stereo embed
235 Q2 capstone

Previous: Lesson 232 — Steam CJK short description
Capstone: Lesson 235 — Q2 spring fest shipping — arc 230–235 closed.

FAQ

Same as Spline LCP guide chapter?
Guide = checklist; 233 = BUILD_RECEIPT + CrUX spot + defer policy JSON.

Must we self-host Spline?
Try L2 first; R3F handoff when iframe budget cannot pass.

CrUX still “No data”?
Ship with lab L4 + documented waiver; refresh L5 after traffic accumulates.


Fest landing LCP is a release gate—defer the iframe, measure, file spline_lcp_fest_receipt, then promote the URL.