Warm functions instead of calling db on first page load

This commit is contained in:
Sam Becker 2025-02-02 22:19:31 -06:00
parent a355375540
commit c69a965dce
4 changed files with 45 additions and 16 deletions

View File

@ -4,6 +4,7 @@ import useSwrInfinite from 'swr/infinite';
import { import {
ReactNode, ReactNode,
useCallback, useCallback,
useEffect,
useMemo, useMemo,
useRef, useRef,
} from 'react'; } from 'react';
@ -14,6 +15,7 @@ import { Photo, PhotoSetCategory } from '.';
import { clsx } from 'clsx/lite'; import { clsx } from 'clsx/lite';
import { useAppState } from '@/state/AppState'; import { useAppState } from '@/state/AppState';
import { GetPhotosOptions } from './db'; import { GetPhotosOptions } from './db';
import useVisible from '@/utility/useVisible';
export type RevalidatePhoto = ( export type RevalidatePhoto = (
photoId: string, photoId: string,
@ -56,7 +58,10 @@ export default function InfinitePhotoScroll({
: [key, size] : [key, size]
, [key]); , [key]);
const fetcher = useCallback(([_key, size]: [string, number]) => const fetcher = useCallback((
[_key, size]: [string, number],
warmOnly?: boolean,
) =>
(useCachedPhotos ? getPhotosCachedAction : getPhotosAction)({ (useCachedPhotos ? getPhotosCachedAction : getPhotosAction)({
offset: initialOffset + size * itemsPerPage, offset: initialOffset + size * itemsPerPage,
sortBy, sortBy,
@ -65,7 +70,7 @@ export default function InfinitePhotoScroll({
tag, tag,
camera, camera,
simulation, simulation,
}) }, warmOnly)
, [ , [
useCachedPhotos, useCachedPhotos,
sortBy, sortBy,
@ -77,18 +82,22 @@ export default function InfinitePhotoScroll({
simulation, simulation,
]); ]);
const { data, isLoading, isValidating, error, mutate, setSize } = const { data, isLoading, isValidating, error, mutate, size, setSize } =
useSwrInfinite<Photo[]>( useSwrInfinite<Photo[]>(
keyGenerator, keyGenerator,
fetcher, fetcher,
{ {
initialSize: 2, initialSize: 0,
revalidateFirstPage: false, revalidateFirstPage: false,
revalidateOnFocus: Boolean(isUserSignedIn), revalidateOnFocus: Boolean(isUserSignedIn),
revalidateOnReconnect: Boolean(isUserSignedIn), revalidateOnReconnect: Boolean(isUserSignedIn),
}, },
); );
useEffect(() => {
fetcher(['', 0], true);
}, [fetcher]);
const buttonContainerRef = useRef<HTMLDivElement>(null); const buttonContainerRef = useRef<HTMLDivElement>(null);
const isLoadingOrValidating = isLoading || isValidating; const isLoadingOrValidating = isLoading || isValidating;
@ -116,6 +125,10 @@ export default function InfinitePhotoScroll({
}, },
} as any), [data, mutate]); } as any), [data, mutate]);
useVisible({ ref: buttonContainerRef, onVisible: () => {
if (size === 0) { advance(); }
}});
const renderMoreButton = () => const renderMoreButton = () =>
<div ref={buttonContainerRef}> <div ref={buttonContainerRef}>
<button <button

View File

@ -4,7 +4,7 @@ import { Tags } from '@/tag';
import { Photo } from '.'; import { Photo } from '.';
import { Cameras } from '@/camera'; import { Cameras } from '@/camera';
import { FilmSimulations } from '@/simulation'; import { FilmSimulations } from '@/simulation';
import { PATH_GRID } from '@/site/paths'; import { PATH_GRID_INFERRED } from '@/site/paths';
import PhotoGridSidebar from './PhotoGridSidebar'; import PhotoGridSidebar from './PhotoGridSidebar';
import PhotoGridContainer from './PhotoGridContainer'; import PhotoGridContainer from './PhotoGridContainer';
import { useEffect } from 'react'; import { useEffect } from 'react';
@ -33,7 +33,7 @@ export default function PhotoGridPage({
return ( return (
<PhotoGridContainer <PhotoGridContainer
cacheKey={`page-${PATH_GRID}`} cacheKey={`page-${PATH_GRID_INFERRED}`}
photos={photos} photos={photos}
count={photosCount} count={photosCount}
sidebar={ sidebar={

View File

@ -1,6 +1,6 @@
'use client'; 'use client';
import { PATH_ROOT } from '@/site/paths'; import { PATH_FEED_INFERRED } from '@/site/paths';
import InfinitePhotoScroll from './InfinitePhotoScroll'; import InfinitePhotoScroll from './InfinitePhotoScroll';
import PhotosLarge from './PhotosLarge'; import PhotosLarge from './PhotosLarge';
@ -13,7 +13,7 @@ export default function PhotosLargeInfinite({
}) { }) {
return ( return (
<InfinitePhotoScroll <InfinitePhotoScroll
cacheKey={`page-${PATH_ROOT}`} cacheKey={`page-${PATH_FEED_INFERRED}`}
initialOffset={initialOffset} initialOffset={initialOffset}
itemsPerPage={itemsPerPage} itemsPerPage={itemsPerPage}
wrapMoreButtonInGrid wrapMoreButtonInGrid

View File

@ -406,15 +406,31 @@ export const getPhotosHiddenMetaCachedAction = async () =>
// Public/Private actions // Public/Private actions
export const getPhotosAction = async (options: GetPhotosOptions) => export const getPhotosAction = async (
areOptionsSensitive(options) options: GetPhotosOptions,
? runAuthenticatedAdminServerAction(() => getPhotos(options)) warmOnly?: boolean,
: getPhotos(options); ) => {
if (warmOnly) {
return [];
} else {
return areOptionsSensitive(options)
? runAuthenticatedAdminServerAction(() => getPhotos(options))
: getPhotos(options);
}
};
export const getPhotosCachedAction = async (options: GetPhotosOptions) => export const getPhotosCachedAction = async (
areOptionsSensitive(options) options: GetPhotosOptions,
? runAuthenticatedAdminServerAction(() => getPhotosCached(options)) warmOnly?: boolean,
: getPhotosCached(options); ) => {
if (warmOnly) {
return [];
} else {
return areOptionsSensitive(options)
? runAuthenticatedAdminServerAction(() => getPhotosCached(options))
: getPhotosCached(options);
}
};
// Public actions // Public actions