fix(gallery): lazy-render skeleton grid for fast loads (#321 follow-up)

The gallery loading skeleton now renders the header bars immediately but
delays the 12-tile placeholder grid by 300ms. Galleries that load
quickly (the common case) never flash the empty grid before the real
photos render — addressing the follow-up reported on #321 — while
slower loads still get a placeholder so the page doesn't sit blank.
This commit is contained in:
Paul Nothaft
2026-05-01 20:55:19 +02:00
parent a5b20ca3fe
commit d9d81372b8
@@ -1,31 +1,41 @@
import React from 'react'; import React, { useEffect, useState } from 'react';
import { Skeleton, SkeletonGalleryGrid } from '../common'; import { Skeleton, SkeletonGalleryGrid } from '../common';
/** /**
* Loading placeholder shown while a gallery is resolving (slug → info → * Loading placeholder shown while a gallery is resolving (slug → info →
* auto-login → photos). Used by GalleryPage during the pre-photos phases and * auto-login → photos). The tile grid is delayed 300ms so fast loads
* by GalleryView while the photos query runs, so the visitor sees one * never flash an empty grid before the real photos render (#321 follow-up).
* continuous skeleton instead of multiple full-page interstitials (#321).
*/ */
export const GallerySkeleton: React.FC = () => ( export const GallerySkeleton: React.FC = () => {
<div className="min-h-screen" style={{ backgroundColor: 'var(--color-background, #fafafa)' }}> const [showGrid, setShowGrid] = useState(false);
<header className="bg-surface border-b border-surface sticky top-0 z-40">
<div className="container py-4"> useEffect(() => {
<div className="flex items-center justify-between"> const t = setTimeout(() => setShowGrid(true), 300);
<div> return () => clearTimeout(t);
<Skeleton height={32} width={200} className="mb-2" /> }, []);
<Skeleton height={20} width={300} />
</div> return (
<div className="flex items-center gap-2"> <div className="min-h-screen" style={{ backgroundColor: 'var(--color-background, #fafafa)' }}>
<Skeleton height={40} width={120} /> <header className="bg-surface border-b border-surface sticky top-0 z-40">
<Skeleton height={40} width={100} /> <div className="container py-4">
<div className="flex items-center justify-between">
<div>
<Skeleton height={32} width={200} className="mb-2" />
<Skeleton height={20} width={300} />
</div>
<div className="flex items-center gap-2">
<Skeleton height={40} width={120} />
<Skeleton height={40} width={100} />
</div>
</div> </div>
</div> </div>
</div> </header>
</header> {showGrid && (
<div className="container mt-6"> <div className="container mt-6">
<Skeleton height={80} className="mb-6" /> <Skeleton height={80} className="mb-6" />
<SkeletonGalleryGrid count={12} /> <SkeletonGalleryGrid count={12} />
</div>
)}
</div> </div>
</div> );
); };