Introduce next/image checks in to optimize url generation

This commit is contained in:
Sam Becker 2026-02-18 09:00:44 -06:00
parent 6ba4cfe1e3
commit 284e5fedfb
2 changed files with 50 additions and 33 deletions

View File

@ -3,12 +3,7 @@
import { Photo } from '@/photo'; import { Photo } from '@/photo';
import { NextImageSize } from '@/platforms/next-image'; import { NextImageSize } from '@/platforms/next-image';
import { IS_PREVIEW } from '@/app/config'; import { IS_PREVIEW } from '@/app/config';
import { import { getOptimizedUrlsForPhotos } from '@/photo/storage';
getOptimizedPhotoUrl,
getOptimizedPhotoUrlForSuffix,
} from '@/photo/storage';
// import { fetchBase64ImageFromUrl } from '@/utility/image';
import { getSignedUrlForUrl } from '@/platforms/storage';
export default async function ImagePhotoGrid({ export default async function ImagePhotoGrid({
photos, photos,
@ -57,31 +52,15 @@ export default async function ImagePhotoGrid({
const cellHeight= height / rows - const cellHeight= height / rows -
(rows - 1) * gap / rows; (rows - 1) * gap / rows;
const photoDataUrls = await Promise.all(photos.map(async({ id, url }) => { const photoUrls = await getOptimizedUrlsForPhotos(
// Check for optimized image first photos,
let optimizedUrl = getOptimizedPhotoUrlForSuffix(url, optimizedSuffix); optimizedSuffix,
// Get presigned URL in case it's required nextImageWidth,
optimizedUrl = await getSignedUrlForUrl(optimizedUrl, 'GET'); IS_PREVIEW,
const optimizedUrlExists = await fetch(optimizedUrl) );
.then(res => res.ok)
.catch(() => false);
// Fall back on `next/image` if optimized image is not available
if (!optimizedUrlExists) {
optimizedUrl = getOptimizedPhotoUrl({
imageUrl: url,
size: nextImageWidth,
addBypassSecret: IS_PREVIEW,
});
}
// const data = await fetchBase64ImageFromUrl(optimizedUrl, 'image/jpeg');
return { id, data: optimizedUrl };
}));
const renderPhoto = ( const renderPhoto = (
{ id, data }: typeof photoDataUrls[number], { id, url }: typeof photoUrls[number],
width: number, width: number,
height: number, height: number,
) => ) =>
@ -96,7 +75,7 @@ export default async function ImagePhotoGrid({
}} }}
> >
<img {...{ <img {...{
src: data, src: url,
style: { style: {
...imageStyle, ...imageStyle,
width: '100%', width: '100%',
@ -126,7 +105,7 @@ export default async function ImagePhotoGrid({
width: cellWidth, width: cellWidth,
height: cellHeight * 2, height: cellHeight * 2,
}}> }}>
{renderPhoto(photoDataUrls[0], cellWidth, cellHeight * 2)} {renderPhoto(photoUrls[0], cellWidth, cellHeight * 2)}
</div> </div>
{/* Small images (R) */} {/* Small images (R) */}
<div style={{ <div style={{
@ -135,12 +114,12 @@ export default async function ImagePhotoGrid({
width: cellWidth, width: cellWidth,
height: cellHeight, height: cellHeight,
}}> }}>
{photoDataUrls.slice(1).map(photo => {photoUrls.slice(1).map(photo =>
renderPhoto(photo, cellWidth, cellHeight), renderPhoto(photo, cellWidth, cellHeight),
)} )}
</div> </div>
</> </>
: photoDataUrls.slice(0, count).map(photo => : photoUrls.slice(0, count).map(photo =>
renderPhoto(photo, cellWidth, cellHeight), renderPhoto(photo, cellWidth, cellHeight),
)} )}
</div> </div>

View File

@ -5,6 +5,7 @@ import {
import { import {
generateFileNameWithId, generateFileNameWithId,
getFileNamePartsFromStorageUrl, getFileNamePartsFromStorageUrl,
getSignedUrlForUrl,
getStorageUrlsForPrefix, getStorageUrlsForPrefix,
uploadFileFromClient, uploadFileFromClient,
} from '@/platforms/storage'; } from '@/platforms/storage';
@ -155,3 +156,40 @@ export const getStorageUrlsForPhoto = async ({ url }: Photo) => {
urls.sort((a, b) => getSortScoreForUrl(a.url) - getSortScoreForUrl(b.url)), urls.sort((a, b) => getSortScoreForUrl(a.url) - getSortScoreForUrl(b.url)),
); );
}; };
export const getOptimizedUrlsForPhotos = async (
photos: Photo[],
optimizedSuffix: OptimizedSuffix,
nextImageWidth: NextImageSize,
addBypassSecret: boolean,
) =>
Promise.all(photos
.map(async({ id, url: _url }) => {
// Check for optimized image first
const optimizedUrl =await getSignedUrlForUrl(
getOptimizedPhotoUrlForSuffix(_url, optimizedSuffix),
'GET',
);
const optimizedUrlExists = await fetch(optimizedUrl)
.then(res => res.ok)
.catch(() => false);
if (optimizedUrlExists) {
return { id, url: optimizedUrl };
} else {
// Fall back on `next/image` if optimized image is not available
const nextImageUrl = getOptimizedPhotoUrl({
imageUrl: _url,
size: nextImageWidth,
addBypassSecret,
});
const nextImageUrlExists = await fetch(nextImageUrl)
.then(res => res.ok)
.catch(() => false);
return { id, url: nextImageUrlExists ? nextImageUrl : undefined };
}
}))
.then(urls =>(urls.every(url => Boolean(url))
? urls
// If any url is defined, return an empty array
: []) as { id: string, url: string }[]);