Cache global category queries

This commit is contained in:
Sam Becker 2025-04-06 14:48:30 -05:00
parent b57283e428
commit 2ce07492ed
7 changed files with 61 additions and 65 deletions

View File

@ -4,10 +4,10 @@ import {
} from '@/photo'; } from '@/photo';
import PhotosEmptyState from '@/photo/PhotosEmptyState'; import PhotosEmptyState from '@/photo/PhotosEmptyState';
import { Metadata } from 'next/types'; import { Metadata } from 'next/types';
import { getDataForCategories } from '@/category/data';
import { getPhotos, getPhotosMeta } from '@/photo/db/query'; import { getPhotos, getPhotosMeta } from '@/photo/db/query';
import { cache } from 'react'; import { cache } from 'react';
import PhotoGridPage from '@/photo/PhotoGridPage'; import PhotoGridPage from '@/photo/PhotoGridPage';
import { getDataForCategoriesCached } from '@/category/cache';
export const dynamic = 'force-static'; export const dynamic = 'force-static';
@ -25,19 +25,14 @@ export default async function GridPage() {
const [ const [
photos, photos,
photosCount, photosCount,
cameras, categories,
lenses,
tags,
recipes,
films,
focalLengths,
] = await Promise.all([ ] = await Promise.all([
getPhotosCached() getPhotosCached()
.catch(() => []), .catch(() => []),
getPhotosMeta() getPhotosMeta()
.then(({ count }) => count) .then(({ count }) => count)
.catch(() => 0), .catch(() => 0),
...getDataForCategories(), getDataForCategoriesCached(),
]); ]);
return ( return (
@ -46,12 +41,7 @@ export default async function GridPage() {
{...{ {...{
photos, photos,
photosCount, photosCount,
cameras, ...categories,
lenses,
tags,
films,
recipes,
focalLengths,
}} }}
/> />
: <PhotosEmptyState /> : <PhotosEmptyState />

View File

@ -8,10 +8,10 @@ import { Metadata } from 'next/types';
import { cache } from 'react'; import { cache } from 'react';
import { getPhotos, getPhotosMeta } from '@/photo/db/query'; import { getPhotos, getPhotosMeta } from '@/photo/db/query';
import { GRID_HOMEPAGE_ENABLED } from '@/app/config'; import { GRID_HOMEPAGE_ENABLED } from '@/app/config';
import { getDataForCategories } from '@/category/data'; import { NULL_CATEGORY_DATA } from '@/category/data';
import PhotoFeedPage from '@/photo/PhotoFeedPage'; import PhotoFeedPage from '@/photo/PhotoFeedPage';
import PhotoGridPage from '@/photo/PhotoGridPage'; import PhotoGridPage from '@/photo/PhotoGridPage';
import { getDataForCategoriesCached } from '@/category/cache';
export const dynamic = 'force-static'; export const dynamic = 'force-static';
export const maxDuration = 60; export const maxDuration = 60;
@ -31,21 +31,16 @@ export default async function HomePage() {
const [ const [
photos, photos,
photosCount, photosCount,
cameras, categories,
lenses,
tags,
recipes,
films,
focalLengths,
] = await Promise.all([ ] = await Promise.all([
getPhotosCached() getPhotosCached()
.catch(() => []), .catch(() => []),
getPhotosMeta() getPhotosMeta()
.then(({ count }) => count) .then(({ count }) => count)
.catch(() => 0), .catch(() => 0),
...(GRID_HOMEPAGE_ENABLED GRID_HOMEPAGE_ENABLED
? getDataForCategories() ? getDataForCategoriesCached()
: [[], [], [], [], [], [], []]), : NULL_CATEGORY_DATA,
]); ]);
return ( return (
@ -55,12 +50,7 @@ export default async function HomePage() {
{...{ {...{
photos, photos,
photosCount, photosCount,
cameras, ...categories,
lenses,
tags,
recipes,
films,
focalLengths,
}} }}
/> />
: <PhotoFeedPage {...{ photos, photosCount }} /> : <PhotoFeedPage {...{ photos, photosCount }} />

View File

@ -298,8 +298,8 @@ export const OG_TEXT_BOTTOM_ALIGNMENT =
export const ADMIN_DEBUG_TOOLS_ENABLED = process.env.ADMIN_DEBUG_TOOLS === '1'; export const ADMIN_DEBUG_TOOLS_ENABLED = process.env.ADMIN_DEBUG_TOOLS === '1';
export const ADMIN_DB_OPTIMIZE_ENABLED = process.env.ADMIN_DB_OPTIMIZE === '1'; export const ADMIN_DB_OPTIMIZE_ENABLED = process.env.ADMIN_DB_OPTIMIZE === '1';
export const ADMIN_SQL_DEBUG_ENABLED = export const ADMIN_SQL_DEBUG_ENABLED =
process.env.ADMIN_SQL_DEBUG === '1' && process.env.ADMIN_SQL_DEBUG === '1';
!IS_BUILDING; // && !IS_BUILDING;
export const APP_CONFIGURATION = { export const APP_CONFIGURATION = {
// Storage // Storage

View File

@ -5,6 +5,8 @@ import {
IS_PRODUCTION, IS_PRODUCTION,
STATICALLY_OPTIMIZED_PHOTO_CATEGORIES, STATICALLY_OPTIMIZED_PHOTO_CATEGORIES,
STATICALLY_OPTIMIZED_PHOTO_CATEGORY_OG_IMAGES, STATICALLY_OPTIMIZED_PHOTO_CATEGORY_OG_IMAGES,
STATICALLY_OPTIMIZED_PHOTO_OG_IMAGES,
STATICALLY_OPTIMIZED_PHOTOS,
} from '@/app/config'; } from '@/app/config';
import { GENERATE_STATIC_PARAMS_LIMIT } from '@/photo/db'; import { GENERATE_STATIC_PARAMS_LIMIT } from '@/photo/db';
import { getPublicPhotoIds } from '@/photo/db/query'; import { getPublicPhotoIds } from '@/photo/db/query';
@ -19,8 +21,8 @@ const logStaticGenerationDetails = (count: number, content: string) => {
export const staticallyGeneratePhotosIfConfigured = (type: StaticOutput) => export const staticallyGeneratePhotosIfConfigured = (type: StaticOutput) =>
IS_PRODUCTION && ( IS_PRODUCTION && (
(type === 'page' && STATICALLY_OPTIMIZED_PHOTO_CATEGORIES) || (type === 'page' && STATICALLY_OPTIMIZED_PHOTOS) ||
(type === 'image' && STATICALLY_OPTIMIZED_PHOTO_CATEGORY_OG_IMAGES) (type === 'image' && STATICALLY_OPTIMIZED_PHOTO_OG_IMAGES)
) )
? async () => { ? async () => {
const photos = await getPublicPhotoIds({ const photos = await getPublicPhotoIds({

View File

@ -1,9 +1,13 @@
import { unstable_cache } from 'next/cache'; import { unstable_cache } from 'next/cache';
import { getCountsForCategories } from './data'; import { getCountsForCategories, getDataForCategories } from './data';
import { KEY_PHOTOS } from '@/photo/cache'; import { KEY_PHOTOS } from '@/photo/cache';
export const getCountsForCategoriesCached = () => export const getDataForCategoriesCached = unstable_cache(
unstable_cache( getDataForCategories,
getCountsForCategories, [KEY_PHOTOS],
[KEY_PHOTOS], );
)();
export const getCountsForCategoriesCached = unstable_cache(
getCountsForCategories,
[KEY_PHOTOS],
);

View File

@ -19,48 +19,68 @@ import { sortTagsByCount } from '@/tag';
import { sortCategoriesByCount } from '@/category'; import { sortCategoriesByCount } from '@/category';
import { sortFocalLengths } from '@/focal'; import { sortFocalLengths } from '@/focal';
export const getDataForCategories = () => [ type CategoryData = Awaited<ReturnType<typeof getDataForCategories>>;
export const NULL_CATEGORY_DATA: CategoryData = {
cameras: [],
lenses: [],
tags: [],
recipes: [],
films: [],
focalLengths: [],
};
export const getDataForCategories = () => Promise.all([
SHOW_CAMERAS SHOW_CAMERAS
? getUniqueCameras() ? getUniqueCameras()
.then(sortCategoriesByCount) .then(sortCategoriesByCount)
.catch(() => []) .catch(() => [])
: [], : undefined,
SHOW_LENSES SHOW_LENSES
? getUniqueLenses() ? getUniqueLenses()
.then(sortCategoriesByCount) .then(sortCategoriesByCount)
.catch(() => []) .catch(() => [])
: [], : undefined,
SHOW_TAGS SHOW_TAGS
? getUniqueTags() ? getUniqueTags()
.then(sortTagsByCount) .then(sortTagsByCount)
.catch(() => []) .catch(() => [])
: [], : undefined,
SHOW_RECIPES SHOW_RECIPES
? getUniqueRecipes() ? getUniqueRecipes()
.then(sortCategoriesByCount) .then(sortCategoriesByCount)
.catch(() => []) .catch(() => [])
: [], : undefined,
SHOW_FILMS SHOW_FILMS
? getUniqueFilms() ? getUniqueFilms()
.then(sortCategoriesByCount) .then(sortCategoriesByCount)
.catch(() => []) .catch(() => [])
: [], : undefined,
SHOW_FOCAL_LENGTHS SHOW_FOCAL_LENGTHS
? getUniqueFocalLengths() ? getUniqueFocalLengths()
.then(sortFocalLengths) .then(sortFocalLengths)
.catch(() => []) .catch(() => [])
: [], : undefined,
] as const; ]).then(([
cameras = [],
lenses = [],
tags = [],
recipes = [],
films = [],
focalLengths = [],
]) => ({
cameras, lenses, tags, recipes, films, focalLengths,
}));
export const getCountsForCategories = async () => { export const getCountsForCategories = async () => {
const [ const {
cameras, cameras,
lenses, lenses,
tags, tags,
recipes, recipes,
films, films,
focalLengths, focalLengths,
] = await Promise.all(getDataForCategories()); } = await getDataForCategories();
return { return {
cameras: cameras.reduce((acc, camera) => { cameras: cameras.reduce((acc, camera) => {

View File

@ -2,31 +2,21 @@ import CommandKClient from './CommandKClient';
import { getPhotosMetaCached } from '@/photo/cache'; import { getPhotosMetaCached } from '@/photo/cache';
import { photoQuantityText } from '@/photo'; import { photoQuantityText } from '@/photo';
import { ADMIN_DEBUG_TOOLS_ENABLED } from '../app/config'; import { ADMIN_DEBUG_TOOLS_ENABLED } from '../app/config';
import { getDataForCategories } from '@/category/data'; import { getDataForCategoriesCached } from '@/category/cache';
export default async function CommandK() { export default async function CommandK() {
const [ const [
count, count,
cameras, categories,
lenses,
tags,
recipes,
films,
focalLengths,
] = await Promise.all([ ] = await Promise.all([
getPhotosMetaCached() getPhotosMetaCached()
.then(({ count }) => count) .then(({ count }) => count)
.catch(() => 0), .catch(() => 0),
...getDataForCategories(), getDataForCategoriesCached(),
]); ]);
return <CommandKClient return <CommandKClient
cameras={cameras} {...categories}
lenses={lenses}
tags={tags}
films={films}
recipes={recipes}
focalLengths={focalLengths}
showDebugTools={ADMIN_DEBUG_TOOLS_ENABLED} showDebugTools={ADMIN_DEBUG_TOOLS_ENABLED}
footer={photoQuantityText(count, false)} footer={photoQuantityText(count, false)}
/>; />;