perf(landing): WebP welcome screenshots + long-cache static assets

The 3 landing screenshots were 2.3 MB of PNG (feed.png alone 1.6 MB, decoded
at 2400x1350 for a ~400px slot) — the biggest LCP/transfer cost on the public
page. Re-encoded to WebP capped at 1600px (~284 KB total, feed 91% smaller).
Also set Cache-Control: content-hashed /assets/* are immutable for a year,
other SPA-root static files (welcome images, favicon, robots) get a 7-day TTL;
index.html stays no-cache. Register image/webp+avif mimetypes so FileResponse
serves the right Content-Type. Lighthouse (dev): Perf 80->93, LCP 1.8s->1.2s.
This commit is contained in:
npeter83 2026-07-04 18:17:11 +02:00
parent 04c4cb05da
commit a07fd82ad6
8 changed files with 27 additions and 4 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 251 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 65 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 144 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 440 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

View file

@ -59,7 +59,7 @@ export default function Welcome() {
{/* App preview */}
<Preview
src="/welcome/feed.png"
src="/welcome/feed.webp"
label={t("welcome.preview.feed")}
className="aspect-video"
onOpen={open}
@ -101,13 +101,13 @@ export default function Welcome() {
{/* Secondary showcase — smaller thumbnails; click to view full size. */}
<section className="mt-12 flex flex-wrap justify-center gap-4">
<Preview
src="/welcome/channels.png"
src="/welcome/channels.webp"
label={t("welcome.preview.channels")}
className="w-full sm:w-72 aspect-[4/3]"
onOpen={open}
/>
<Preview
src="/welcome/playlists.png"
src="/welcome/playlists.webp"
label={t("welcome.preview.playlists")}
className="w-full sm:w-72 aspect-[4/3]"
onOpen={open}