[Next.js] 이미지 최적화 관련

Assets

Next.js 또한 static assets를 사용할 수 있으며 이미지와 같은 assets를 사용할 때 유용한 기능들을 제공한다.

다음과 같은 이미지가 있다고 한다면,

기존에는 img 태그를 사용하여 이미지를 사용해왔다.

// pages/index.tsx
const Home: NextPage = () => {
  return (
    <div>
      <main>
        <img src='/images/cat.jpg' alt='cat' />
      </main>
    </div>
  )
}

하지만 이렇게 사용한다면 이 이미지를 다양한 화면 크기에 대응할 수 있도록 적절한 브레이크 포인트를 설정해주거나 최대한 사용자가 보이는 부분부터 로드되도록 처리하는 등의 이미지 최적화를 해야했다.

다음의 그림만 보더라도 실제 사용한 크기에 비해 과도한 크기를 사용하고 있는 것을 확인할 수 있다.

그래서 이러한 불편함을 해결해주고자 Next에서는 Image 컴포넌트를 제공하고 있다.

// pages/index.tsx

import Image from 'next/image';

const Home: NextPage = () => {
  return (
    <div>
      <main>
        <img src='/images/cat.jpg' alt='cat' />
      </main>
    </div>
  )
}

Image 컴포너트에는 필수적으로 src, width, height 속성이 필요하다.

Image 컴포넌트를 사용하면 WebP을 지원하는 브라우저에서는 모바일에서 사용자가 필요 이상의 이미지를 다운받게 되어 리소스가 낭비되는 것을 방지시켜 주며 사용자가 보지 않는 부분은 Lazy Loading을 사용하는 등의 이미지 최적화 기능을 제공해준다.

사용한 예시는 다음과 같으며 위에는 img 태그를 사용한 결과이며 아래는 Image 컴포넌트를 사용한 결과이다.

이미지 최적화관련해서 도움을 많이 받았던 기술블로그이다.
https://tech.oliveyoung.co.kr/tech/2111220929/

Metadata

이 부분은 저번 포스팅에서 확인했지만 추가적으로 알게된 내용은 custom Document라고 하는 것이다.

각 페이지별로 import Head from 'next/head';를 import하여 페이지의 메타데이터를 수정할수도 있지만 pages/_document.tsx를 오버라이딩하여 모든페이지에서 공통적으로 활용할 <head><body> 태그를 커스터마이징 할 수 있다.

마찬가지로 pages에 디렉토리 하위에 _document.tsx로 생성해주어야하며 Document를 extends 해주어야 한다.

여기서는 문서의 저자를 정의하는 태그를 추가해보았다.

주의할점은 Head 컴포넌트가 next/head가 아니라 next/document라는 점이다.

import Document, { Html, Head, Main, NextScript, DocumentContext } from 'next/document'

class MyDocument extends Document {
  static async getInitialProps(ctx: DocumentContext) {
    const originalRenderPage = ctx.renderPage

    // Run the React rendering logic synchronously
    ctx.renderPage = () =>
      originalRenderPage({
        // Useful for wrapping the whole react tree
        enhanceApp: (App) => App,
        // Useful for wrapping in a per-page basis
        enhanceComponent: (Component) => Component,
      })

    // Run the parent `getInitialProps`, it now includes the custom `renderPage`
    const initialProps = await Document.getInitialProps(ctx)

    return initialProps
  }

  render() {
    return (
      <Html>
        <Head>
          <meta name="author" content="Danji-ya" /> 
        </Head>
        <body>
          <Main />
          <NextScript />
        </body>
      </Html>
    )
  }
}

그러면 다음과 같이 모든페이지에 추가한 메타태그가 보이게 된다.

중간 느낀점

지금까지만 보더라도 기존의 react를 사용하면서 겪었던 라우팅의 불편함, 이미지 최적화, 코드 스플리팅을 사용하여 로딩 성능 개선등과 같은 일들을 너무나도 쉽게 적용할 수 있다는점에서 프레임워크가 얼마나 좋은건지 다시 한번 더 알 수 있었다.👍

좋은 웹페이지 즐겨찾기