Front-end/React

[Next13] next/image 속성으로 이미지 최적화 적용하기

helloyukyung 2023. 10. 3. 17:58

loading

loading = 'lazy' // {lazy} | {eager}

기본값은 lazy로 사용 된다.
lazy일 경우, viewport에서 계산 된 거리에 도달할 때까지 이미지 로드를 연기해준다.
만약 eager일 경우 이미지를 즉시 로드해준다.

Recommendation: This property is only meant for advanced use cases. Switching an image to load with eager will normally hurt performance. We recommend using the priority property instead, which will eagerly preload the image.

 

하지만, eager로 이미지를 긴급 로드 해버리면 일반적으로 성능이 저하된다.
따라서 아래 priority속성을 사용해, 이미지를 eagerly preload 하는 것이 좋다.

priority

priority={false} // {false} | {true}

기본값은 false이다. true인 경우, 이미지는 높은 우선순위 및 사전 로드로 간주되며,이 경우 lazyLoading이 자동 비활성화 된다.
따라서 메인 콘텐츠에 로드(LCP:Largest Contentful Paint) 되는 이미지에 사용하는 것이 좋다.

placeholder

placeholder = 'empty' // "empty" | "blur" | "data:image/..."

placeholder='blur'속성일 경우 정적 이미지의 경우, 자동으로 blurDataUrl가 채워지지만,
동적 이미지의 경우 blurDataURL속성을 추가로 제공해야 한다.
blurDateUrl는 base64 형태의 이미지를 받는다.

 

Plaiceholder

Beautiful image placeholders, without the hassle.

plaiceholder.co

import {getPlaiceholder} from 'plaiceholder'

plaiceholder를 사용해 base64형태의 이미지를 가져와 BlurDataUrl에 전달해주었다.

import {getPlaiceholder} from 'plaiceholder'
export default async function getBase64(imageUrl: string) {
  try {
    const res = await fetch(imageUrl)
    if (!res.ok) {
      throw new Error(`Failed to fetch Image ${res.status} ${res.statusText}`)
    }
    const buffer = await res.arrayBuffer()
    const {base64} = await getPlaiceholder(Buffer.from(buffer))

    return base64
  } catch (e: any) {
    console.log(e.stack)
  }
}
import getBase64 from '@/lib/getLocalBase64'
import Image, {ImageProps} from 'next/image'

interface BlurImageProps extends ImageProps {
  src: string
}

export default async function BlurImage(props: BlurImageProps) {
  const blurUrl = await getBase64(props.src)

  return <Image {...props} placeholder="blur" blurDataURL={blurUrl} />
}

결과

왼 : base64 이미지 blur 적용  / 후: 이미지 로드 후 서버 이미지 적용

블러 이미지를 표시하면 이미지가 로딩 중임을 사용자에게 시각적으로 알려준다.
이렇게 하면 사용자가 페이지가 여전히 로딩 중임을 이해하고 기다릴 수 있도록 도와줄 수 있을 것이다.