Skip to content

Commit 04204c1

Browse files
committed
Optimize responsive hero loading
1 parent ec482af commit 04204c1

5 files changed

Lines changed: 34 additions & 32 deletions

File tree

375 KB
Loading
365 KB
Loading

‎scripts/build-hero-art.mjs‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ const sourcePath = path.join(
99
"assets-src/hero/compbio-research-atlas-chroma-source.png",
1010
);
1111
const outputDirectory = path.join(projectRoot, "public/hero");
12-
const outputWidths = [800, 1600];
12+
const outputWidths = [800, 1200, 1600];
1313

1414
const clamp = (value, minimum = 0, maximum = 1) =>
1515
Math.max(minimum, Math.min(maximum, value));
Lines changed: 33 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,23 @@
11
import { cn } from "@/lib/utils";
22
import { publicAssetPath } from "@/lib/publicAsset";
33
import { useTheme } from "next-themes";
4-
import { useEffect, useState } from "react";
4+
import { useEffect, useRef, useState } from "react";
55

6-
const heroAssetPath = (theme: "light" | "dark", width: 800 | 1600) =>
6+
const heroAssetPath = (theme: "light" | "dark", width: 800 | 1200 | 1600) =>
77
publicAssetPath(`/hero/compbio-research-atlas-${theme}-${width}.webp`);
88

9+
const heroSrcSet = (theme: "light" | "dark") =>
10+
[800, 1200, 1600]
11+
.map((width) => `${heroAssetPath(theme, width as 800 | 1200 | 1600)} ${width}w`)
12+
.join(", ");
13+
914
const heroImageProps = {
1015
alt: "",
1116
width: 1600,
1217
height: 1200,
1318
decoding: "async" as const,
1419
draggable: false,
20+
fetchpriority: "high" as const,
1521
loading: "eager" as const,
1622
sizes: "(min-width: 1024px) 72vw, (min-width: 640px) 110vw, 135vw",
1723
};
@@ -22,34 +28,42 @@ interface HeroScienceGraphicProps {
2228

2329
export const HeroScienceGraphic = ({ className }: HeroScienceGraphicProps) => {
2430
const { resolvedTheme } = useTheme();
25-
const [mounted, setMounted] = useState(false);
31+
const [darkMedia, setDarkMedia] = useState("(prefers-color-scheme: dark)");
32+
const themeReady = useRef(false);
2633

2734
useEffect(() => {
28-
setMounted(true);
29-
}, []);
35+
if (!resolvedTheme) return;
3036

31-
const documentTheme =
32-
mounted && document.documentElement.classList.contains("dark")
37+
const systemTheme = window.matchMedia("(prefers-color-scheme: dark)").matches
3338
? "dark"
3439
: "light";
35-
const theme = mounted && (resolvedTheme === "dark" || (!resolvedTheme && documentTheme === "dark"))
36-
? "dark"
37-
: "light";
40+
41+
if (!themeReady.current) {
42+
themeReady.current = true;
43+
if (resolvedTheme === systemTheme) return;
44+
}
45+
46+
setDarkMedia(resolvedTheme === "dark" ? "all" : "not all");
47+
}, [resolvedTheme]);
3848

3949
return (
4050
<span
4151
className={cn("hero-science-art block", className)}
4252
aria-hidden="true"
4353
>
44-
<img
45-
{...heroImageProps}
46-
src={heroAssetPath(theme, 1600)}
47-
srcSet={`${heroAssetPath(theme, 800)} 800w, ${heroAssetPath(theme, 1600)} 1600w`}
48-
className={cn(
49-
"h-auto w-full select-none object-contain transition-opacity duration-200",
50-
mounted ? "opacity-100" : "opacity-0",
51-
)}
52-
/>
54+
<picture>
55+
<source
56+
media={darkMedia}
57+
srcSet={heroSrcSet("dark")}
58+
sizes={heroImageProps.sizes}
59+
/>
60+
<img
61+
{...heroImageProps}
62+
src={heroAssetPath("light", 800)}
63+
srcSet={heroSrcSet("light")}
64+
className="h-auto w-full select-none object-contain"
65+
/>
66+
</picture>
5367
</span>
5468
);
5569
};

‎src/index.css‎

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -326,7 +326,6 @@
326326

327327
.hero-science-art {
328328
transform-origin: center;
329-
animation: hero-science-drift 10s ease-in-out infinite;
330329
}
331330

332331
.site-logo-system-dark {
@@ -444,17 +443,6 @@
444443
}
445444
}
446445

447-
@keyframes hero-science-drift {
448-
0%,
449-
100% {
450-
transform: translate3d(0, 0, 0);
451-
}
452-
453-
50% {
454-
transform: translate3d(0, -5px, 0);
455-
}
456-
}
457-
458446
@media (prefers-reduced-motion: reduce) {
459447
html {
460448
scroll-behavior: auto;

0 commit comments

Comments
 (0)