ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Next.js] Image 컴포넌트에 대해 (feat. local & remote)
    FrontEnd/Next.js 2022. 12. 22. 19:15

    1. Next.js 가 제공하는 Image 컴포넌트(공식문서 링크) 특징과 장점

    • 특징
      • lazy loading 
      • 이미지 사이즈 최적화
      • placeholder (Local Image일 경우)
    • 장점
      • 성능 향상 : 적절한 사이즈 이미지 서빙 & 작은 용량의 포맷 사용 가능
      • 시각적인 안전성: placeholder를 통해 이미지 로드전 CLS(Cumulative Layout Shift) 방지
      • 빠른 페이지 로딩: lazy loading & 이미지 사이즈 최적화, placeholder를 통한


    2. lazy loading 

    • 이미지 로드 하는 시점을 필요할 때 까지 지연시키는 기술을 의미한다. ( 페이지 로드 속도 빨라지는 이점)
    • 사용자가 이미지가 나올때까지 스크롤 하지 않으면 이미지는 로드 되지 않는다.
    • Next.js는 사용자가 특정 이미지가 위치한 곳으로 스크롤 했다면 그때 이미지를 다운로드한다.
    • 즉 사용자가 보고 있는 것(만||까지) 로드 ( prioriy=true ||  loading="eager" 를 설정하면 적용x)
    • cf ) chrome 76 버전 이상부터는 img태그에 loading='lazy' 속성 부여시 구현 가능

    3. 이미지 사이즈 최적화

    • Next.js 이미지 서버는 최초 요청 시에 사용자의 디바이스에 맞는 이미지 사이즈를 만듬
    • 이후 캐시 만료전까지는 캐시 된 이미지가 제공되어서 첫번째 요청보다 더 빠르게 이미지 서빙
    • 캐시 만료 이후 요청시에는 오래된 이미지를 우선 제공하고, 백그라운드에서 이미지 최적화를 다시 진행
    • srcSet을 미리 지정해서 디바이스 크기 별로 이미지 다운로드 지원(layout prop 설정에 따라 특정 srcSet목록 변경)

    4. placeholder

    • src가 public 폴더에 담겨진 local 이미지일 경우 로드 되기 전 흐릿한 이미지를 미리 사용자에게 제공해줌
    • 어떤 이미지인지 알기 때문에 Next.js는 이러한 서비스를 제공함 (build 타임에 생성)
    • placeholder = "blur" //흐릿한 이미지는 곧 블러 이미지라고 부름
    • romote 이미지는 api응답이 있기 전까지 어떤 이미지인지 모르므로 해당 속성을 줬을시 에러 발생

     

    5. local 이미지 & remote 이미지 사용법

    • local 이미지 사용법
      • src에 해당 이미지의 경로를 적는게 아닌 import 를 통해 접근
      • plcaholder는 local이미지에 적용 가능한 옵션값
    import Image from "next/image";
    import profile from "../public/me.png";
    
    function Me() {
      return (
        <Image
          src={profile}
          alt="it's me"
          placeholder="blur" 
        />
      );
    }
    • remote 이미지
      • 리모트 - api가 응답하기를 기다리는
        그래야 소스, 이미지 url 알수 있는
        리모트는 로컬만큼 최적화x
        흐릿한 이미지 미리 생성x placeholder=blur 쓰면 오류
        api 도착 전까지 뭔지 모르므로
        ㄱ.넥스트는 해당 이미지가 업로드 되는 서버 궁금해함( 서버의 도메인을 config에)
         ㄴ. 레이지 로딩을 돕기 위해 width와 height값 필수로 적어줘야함 (or layout='fill')
        ㄷ. 프론트 페이지는 더이상 클라우드 플레어를 상대하지 않음. ==> 
        프론트 엔드는 넥스트 이미지 서버에게 말하고 있다.
        넥스트 이미지 서버는 클라우드에 이미지를 요청하고
        넥스트 이미지서버는 네가 원하는 버전의 이미지를 제공  

      • remote 이미지는 api가 응답하기를 기다림. 이미지 url을 알아야 src가 입혀지니까
      • placeholder='blur' 오류 ( next는 뭔 이미지인지 모름)
      • Next.js 이미지 서버는 해당 이미지가 업로드 되는 서버를 궁금해함 -> next.config.js에 명시
        • 모든 url를 허용하면 악의를 가진 사용자에 의해 공격 받을 가능성 생김
        • next.config.js 파일에 CDN의 host를 명시해줘야함
      • Lazy loading을 돕기 위해 (width & height) || layout 속성을 부여해줘야함 
      • front페이지는 더이상 이미지 서버를 상대하지 않음 -> Next.js 이미지 서버가 클라우드에 이미지를 요청
      • 이후 Next.js 이미지 서버는 사용자 || 개발자가 원하는 버전의 이미지를 제공
    /** @type {import('next').NextConfig} */
    module.exports = {
      reactStrictMode: true,
      images: {
        domains: ["imagedelivery.net"],
      },
    };
    <Image
      src={`https://imagedelivery.net/blablabla/${data?.image}/public`}
      width={48}
      height={48}
    />
    • Next.js 는 romte될 이미지의 크기를 모르므로 명시적으로 알려줌.( 위의 코드는 width와 height으로 알려준겨)
    • width와 height 대신에 layout 속성을 통한 크기 명시 (예시는 추후 업뎃 )
      • layout="intrinsic" || layout ="fixed"를 사용할때는, w와h는 픽셀내에서 높이와 너비를 렌더링 되는 값이 속성 부여됨. 요 속성은 얼마나 큰 이미지를 나타낼건지에 영향줌
      • layout="responsive"||  layout="fill"를 사용할때는, w와h는 이미지 본연 크기에 의해 채워짐. 요 속성은 컨테이너에서의 비율 측면으로 영향 끼침
    1. intrinsic - default value for the layout prop. Gives the image enough space to render using its original width and height dimension. Try out a demo here.
    1. fixed - sizes the image to fit the exact width and height props values. Generates a srcSet with pixel density descriptors of 1x and 2x. Try it out here.
    2. fill - causes an image to expand in width and height to fill its parent element's width and height. Ensure you add position: relative to the parent element. This value is usually used with the objectFit property and is recommended for images in which you don't know their sizes in advance. Check out a demo here.
    3. responsive - scales the image to fit the width of its parent container. Ensure you add display: block to the parent container. Try out a demo here.

      // https://refine.dev/blog/using-next-image/#optional-props

     

     

    참고: https://refine.dev/blog/using-next-image/#optional-props

    https://fe-developers.kakaoent.com/2022/220714-next-image/

Designed by Tistory.