기존 ImageFallback 컴포넌트
next.config.js
에 unoptimized: true
설정이 되어있길래 의아해서 삭제했었는데, vercel 프리뷰때에만 설정을 하고 실제 프로덕션에는 unoptimized: true
설정을 해제하는 것으로 나중에 확인을 하였습니다. import React, { useEffect, useState } from "react";
import NextImage from "next/image";
const DEFAULT_THUMBNAIL = "/default_thumbnail.svg";
export type ProductImageWithFallbackProps = {
alt: string;
thumbId: string | undefined;
// 페이지의 첫 화면 스크롤 내에 보여지는 아이템들에게는 priority 속성을 부여
priority?: boolean;
size?: "sm" | "md" | "lg" | "xs" | "thumb" | "raw";
} & Omit<React.ComponentProps<typeof NextImage>, "src" | "alt">;
export const ProductImageWithFallback = ({
priority,
thumbId,
alt,
size = "lg",
...rest
}: ProductImageWithFallbackProps) => {
const [isSuccessLoaded, setIsSuccessLoaded] = useState(false);
const [src, setSrc] = useState(
thumbId ? `${process.env.NEXT_PUBLIC_CF_IMAGE_URL}/${thumbId}${size ? "?size=" + size : ""}` : DEFAULT_THUMBNAIL,
);
const setFallbackImageOnError = () => {
if (!src.startsWith(process.env.NEXT_PUBLIC_IMAGE_URL as string) && thumbId) {
setSrc(`${process.env.NEXT_PUBLIC_IMAGE_URL}/${thumbId}`);
setIsSuccess(true);
} else {
setSrc(DEFAULT_THUMBNAIL);
}
};
useEffect(() => {
// 이미지 로딩을 하는 데 1.5s가 지나도 로딩이 완료되지 않을 시 defaultThumbanil로 src 설정해주는 코드
const timer = setTimeout(() => {
priority && !isSuccessLoaded && setSrc(DEFAULT_THUMBNAIL);
}, 1500);
return () => clearTimeout(timer);
}, [priority, isSuccessLoaded]);
return (
<NextImage
src={src}
alt={alt}
priority={priority}
onError={setFallbackImageOnError}
onLoadingComplete={(result) => {
// 기존의 brokenImage 조건을 좀 더 범위를 넓혔습니다
if (result.naturalWidth <= 30) {
setSrc(DEFAULT_THUMBNAIL);
} else {
setIsSuccessLoaded(true);
}
}}
{...rest}
/>
);
};
brokenImage 조건을 기존 result.naturalWidth === 0
에서
result.naturalWidth <= 30
으로 좀 더 범위를 넓혔습니다.
유저가 페이지에 들어왔을 때 보여지는 영역의 아이템들에게 이미지 로딩을 하는 데 1.5s가 지나도 로딩이 완료되지 않을 시 defaultThumbanil
로 src
를 설정해주는 코드를 추가했습니다.