인터랙션

[Blur-up] 작은 LQIP 깔고 원본 페이드인

24×18 픽셀짜리 LQIP을 먼저 받아 흐릿하게 깔아두고, 원본이 도착하면 부드럽게 페이드인. 빈 회색 박스를 보지 않으니 체감 속도가 확 빨라지는 클래식 패턴.

ReactTailwind CSSCSS filter (blur)object-coverpicsum.photos
라이브 데모
새 탭에서 열기
데모 불러오는 중…

제작 과정

한 줄 요약

24×18 픽셀짜리 LQIP을 흐릿하게 먼저 깔고 원본 도착 시 페이드인 — 빈 회색 박스 깜빡임을 없애 체감 속도를 끌어올린다.

이럴 때 필요해요

이미지 로드가 짧아도 빈 회색 박스가 깜빡이면 사용자는 "느리다"고 느낀다. LQIP(Low Quality Image Placeholder)은 아주 작은 이미지를 즉시 받아 흐릿한 미리보기로 깔아두고 원본이 도착하면 부드럽게 페이드인해 이 깜빡임을 없앤다. Medium·Unsplash·Next/Image의 placeholder="blur"가 모두 이 방식.

어떻게 동작하나

  1. LQIP과 원본을 같은 aspect-[4/3] 컨테이너에 absolute로 겹쳐 놓고, 원본의 onLoad에서 opacity 0→100으로 페이드. LQIP는 동시에 페이드아웃.
  2. LQIP에 scale-110 + blur-xl — blur 필터는 가장자리가 투명해지므로 살짝 키워서 가린다.
  3. "다시 로드"는 version state를 올려 key를 바꾸는 식 — 컴포넌트가 remount되며 loaded=false부터 깨끗하게 재시작.
  4. 이미지 URL에 ?v=${version} 캐시 무효화 쿼리를 붙여 실제 네트워크 응답을 새로 받게.

놓치기 쉬운 것

  • display:none 대신 opacity로 페이드 — display를 토글하면 트랜지션이 끊긴다.
  • 컨테이너에 aspect-ratio를 미리 안 주면 원본 도착 순간 높이가 변해 CLS가 치솟는다.
  • 실무에선 LQIP을 빌드 타임에 base64 dataURL로 인라인 — 별도 요청 없이 즉시 페인트되는 게 핵심. 이 데모는 학습용으로 picsum URL을 두 번 호출한 형태.
  • LQIP·원본 둘 다 object-cover로 맞춰야 페이드 도중 위치가 안 어긋난다.

이런 곳에 써요

  • 블로그 본문 첨부 이미지 (긴 글, 다수의 사진)
  • 상품 그리드·갤러리 페이지
  • Hero 이미지 — 위에 카피가 얹히는 케이스라 빈 박스가 더 거슬린다

소스 코드

· 데모 페이지에서 자동 추출
import type { Metadata } from "next";
import { ImageBlurUpDemo } from "./-components/ImageBlurUpDemo";

export const metadata: Metadata = {
  title: "Image Blur-up — LQIP 페이드인 (데모)",
  description:
    "작은 LQIP을 먼저 받아 흐리게 깔아두고, 원본이 도착하면 페이드인하는 이미지 로드 패턴. 빈 회색 박스를 줄여 체감 속도를 끌어올리는 클래식.",
  robots: { index: false, follow: false },
};

export default function Page() {
  return <ImageBlurUpDemo />;
}
45조회수

댓글