Splash only on fresh visit (sessionStorage); preload LCP logo; draft perf blog post

- Splash is now a one-time intro per session: once entered (scroll or click) a
  refresh skips it, so you can't scroll back up into it mid-page.
- Preload the splash logo <img> (the mobile LCP element) at high priority.
- Draft blog post on keeping an animated hero without tanking Core Web Vitals
  (draft: true, for review).
This commit is contained in:
jwinterm
2026-06-06 18:49:50 -04:00
parent 980bd963fc
commit 945529af33
2 changed files with 66 additions and 1 deletions
+10 -1
View File
@@ -33,7 +33,11 @@ export default function Home() {
// the main hero, on desktop and mobile. Runs before paint, so the splash never
// flashes for these visitors.
useIsoLayoutEffect(() => {
if (window.matchMedia("(prefers-reduced-motion: reduce)").matches) {
const reduced = window.matchMedia("(prefers-reduced-motion: reduce)").matches;
// The splash is a one-time intro per session: once entered, a refresh (even
// from mid-page) skips it so you can't scroll back up into it.
const alreadyEntered = sessionStorage.getItem("such:entered") === "1";
if (reduced || alreadyEntered) {
setEntered(true);
setSplashUp(false);
}
@@ -53,6 +57,7 @@ export default function Home() {
([entry]) => {
if (!entry.isIntersecting) {
restoreScroll.current = Math.max(0, window.scrollY - el.offsetHeight);
sessionStorage.setItem("such:entered", "1");
setEntered(true);
setSplashUp(false); // scrolled past: just unmount, no overlay fade needed
}
@@ -90,6 +95,7 @@ export default function Home() {
const enterFromButton = () => {
restoreScroll.current = 0;
sessionStorage.setItem("such:entered", "1");
setEntered(true);
setLeaving(true);
// Keep the splash mounted briefly as a fixed, fading overlay so it cross-fades
@@ -99,6 +105,9 @@ export default function Home() {
return (
<main className="relative flex flex-col items-center overflow-hidden">
{/* The splash logo is the homepage LCP element on mobile; fetch it immediately
so it isn't queued behind render-blocking CSS/JS. */}
<link rel="preload" as="image" href="/images/branding/splash-such.svg" fetchPriority="high" />
<DynamicBackground nebulaPosition={nebulaPosition} visible={entered} />
<Header floating visible={entered} />