Suspense와 이미지 적재하기

const imagePromise = new Promise((resolve) => {
  const img = new Image();  // 새 이미지 객체 생성
  img.onload = () => rseolve(img) // 이미지 적재가 끝나면 프로미스 해소
  img.src = "path/to/image/image.png" // 소스 지정해 이미지 적재 시작
})
  • 캐시를 위해 리엑트 쿼리를 사용!?

  • 동일한 src를 사용하는 여러 Img 컴포넌트를 사용해도 이미지를 여러 번 적재하지 않음

  • 리엑트 쿼리는 캐싱된 Image 객체를 반환

    • 이미지 자체는 브라우저에 의해 캐싱됨

const Img = ({src, alt, ...props}) => {
  const {data: imgObject} = useQuery(
    src,
    () => new Promise((resolve) => {
      const img = new Image();
      img.onload = () => resolve(img);
      img.src = src;
    }),
    {suspense: true}
  )
 
  return <img src={imgObject.src} alt={alt} {...props} /> 
}
  • Img와 Suspense를 사용하는 컴포넌트 예시

import { Suspense } from 'react';
import { useQuery } from 'react-query';

const Avatar = ({src, alt, fallbackSrc, ...props}) => {
  return {
    <div>
      <Suspense
        fallback={<img src={fallbackSrc} alt="Fallback Avatar" />}
      >
        <Img src={src} alt={alt} {...props} />
      </Suspense>
    </div>
  }
}

페이지의 head 엘리먼트에서 rel='prefetch'와 함께 link 엘리먼트를 추가해서 폴백 이미지를 미리 적재할 수도 있다.

리엑트 쿼리를 사용해 이미지나 데이터를 미리 적재하는 방법

  • queryClient.prefetchQuery

    • 메서드를 호출해서 가능한 빨리 리소스를 적재하기

  • 폭포수 방식의 데이터 적재(한 자원이 다 적재된 후에 다음 자원 적재를 시작하는 방식)을 최대한 피해라.

Last updated