Speed up timeline load with portrait thumbs, bootstrap API, and caching.
Add catalog bootstrap endpoint, portrait thumbnail pipeline, lazy queued timeline images, gzip compression, and 3D texture throttling with code-split VirtualGallery.
This commit is contained in:
@@ -1,8 +1,8 @@
|
||||
import { useState, useEffect, useCallback, useMemo, useRef } from 'react';
|
||||
import { useState, useEffect, useCallback, useMemo, useRef, lazy, Suspense } from 'react';
|
||||
import Timeline from '../components/Timeline';
|
||||
import TimelineEventGuides from '../components/TimelineEventGuides';
|
||||
import MovementBands from '../components/MovementBands';
|
||||
import VirtualGallery from '../components/VirtualGallery';
|
||||
const VirtualGallery = lazy(() => import('../components/VirtualGallery'));
|
||||
import PaintingDetailView from '../components/PaintingDetail';
|
||||
import ArtistBio from '../components/ArtistBio';
|
||||
import CheckupPage from '../pages/CheckupPage';
|
||||
@@ -144,23 +144,16 @@ export default function HomePage() {
|
||||
(async () => {
|
||||
try {
|
||||
setLoading(true);
|
||||
const b = await api.getBounds();
|
||||
const min = b.min_year ?? -800;
|
||||
const max = b.max_year ?? 2025;
|
||||
const catalog = await api.getCatalogBootstrap();
|
||||
if (cancelled) return;
|
||||
|
||||
const min = catalog.bounds.min_year ?? -800;
|
||||
const max = catalog.bounds.max_year ?? 2025;
|
||||
setBounds({ min, max });
|
||||
setViewStart(min);
|
||||
setViewEnd(max);
|
||||
|
||||
const [timeline, artistList] = await Promise.all([
|
||||
api.getTimeline(min, max),
|
||||
api.getTimelineArtists(),
|
||||
]);
|
||||
if (cancelled) return;
|
||||
|
||||
setTimelineData(timeline);
|
||||
setArtists(artistList);
|
||||
setTimelineData({ eras: catalog.eras, movements: catalog.movements });
|
||||
setArtists(catalog.artists);
|
||||
setError(null);
|
||||
} catch {
|
||||
if (!cancelled) setError('Could not load gallery data. Is the server running?');
|
||||
@@ -407,6 +400,7 @@ export default function HomePage() {
|
||||
|
||||
const handleArtistClick = async (artistId: number) => {
|
||||
try {
|
||||
await api.preloadArtistImages(artistId).catch(() => undefined);
|
||||
const data = await api.getArtist(artistId);
|
||||
openArtistGallery(artistId, data);
|
||||
} catch {
|
||||
@@ -605,6 +599,7 @@ export default function HomePage() {
|
||||
aria-hidden={!galleryActive}
|
||||
>
|
||||
{displayGallery.kind === 'artist' ? (
|
||||
<Suspense fallback={null}>
|
||||
<VirtualGallery
|
||||
key={`artist-${displayGallery.artistId}-${galleryRevision}-${galleryActive ? 'live' : 'parked'}`}
|
||||
mode="artist"
|
||||
@@ -622,7 +617,9 @@ export default function HomePage() {
|
||||
})
|
||||
}
|
||||
/>
|
||||
</Suspense>
|
||||
) : (
|
||||
<Suspense fallback={null}>
|
||||
<VirtualGallery
|
||||
key={`movement-${displayGallery.movementId}-${galleryRevision}-${galleryActive ? 'live' : 'parked'}`}
|
||||
mode="movement"
|
||||
@@ -632,6 +629,7 @@ export default function HomePage() {
|
||||
onPaintingClick={handlePaintingClick}
|
||||
onBack={() => setView({ type: 'timeline' })}
|
||||
/>
|
||||
</Suspense>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
|
||||
Reference in New Issue
Block a user