반응형

NextJS Image Component

Image Component를 사용하는 이유

Image는 img 태그의 확장입니다. 

Core Web Vitals를 달성하기 위해 다양한 성능 최적화 기능이 내장되어 있습니다. 

Core Web Vitals는 사용자 경험을 측정하는 중요한 지표이면서, 구글 검색 순위에 반영됩니다.

 

Image Component에 내장된 최적화 내용

  • 향상된 성능(Improved Performance): 최신 이미지 형식을 사용하여 각 장치에 대해 항상 올바른 크기의 이미지를 제공
  • 시각적 안정성(Visual Stabillity): 자동으로 누적 레이아웃 이동방지( Cumulative Layout Shift [ CLS ] )
  • 더 빠른 페이지 로드(Faster Page Loads): 이미지가 뷰포트에 들어왔을 때만 로드되기 떄문에 초기 페이지 로드 속도가 빠름
  • 자산 유연성(Asset Flexibillity): 외부에 저장되어 있는 이미지까지도 리사이징 가능

 

NextJS에서 <Image /> 대신 <img />를 사용하게 될 경우 아래와 같은 경고 문구가 나오게 됩니다.

Warning: Using `<img>` could result in slower LCP and higher bandwidth. Use `<Image />` from `next/image` instead to utilize Image Optimization. See: https://nextjs.org/docs/messages/no-img-element @next/next/no-img-element

 

img를 사용하면 LCP속도가 느려지고 대역폭이 커질 수 있기 때문에, <Image />를 사용하여 이미지를 최적화 시키라는 내용입니다.

 

 

Image Component 사용하기

next.config.js

const module.exports = {
    images: {
        domains: ["도메인 주소"]
    }
}

외부에서 이미지를 불러오기 위해서는 next.config.js에서 도메인을 설정해야 합니다.

 

app.tsx

<Image src={이미지주소} alt={이미지이름} layout="fill" />

<Image src={이미지주소} alt={이미지이름} width={100} height={100} />

정적으로 불러오는 이미지 파일과 layout 값이 "fill"인 이미지를 제외하고는 width와 height값이 필수적으로 들어가야 합니다.

width와 height를 필수적으로 입력하는 이유는 CLS를 방지하기 위해서 입니다.

 

next/image 13이후 버전에서 변경된 내용

13버전 이후 아래처럼 layout에 하이픈이 그어졌습니다..

react_devtools_backend.js:2655 Image with src " 이미지 주소내용... " has legacy prop "layout". Did you forget to run the codemod?

 


 

번외:: 위 내용 때문에 <Image />에서 <img />로 갈아탔다가 아래와 같은 경고문을 받게 되었습니다.

Warning: Using `<img>` could result in slower LCP and higher bandwidth. Use `<Image />` from `next/image` instead to utilize Image Optimization. See: https://nextjs.org/docs/messages/no-img-element @next/next/no-img-element

<img />를 사요요하면 LCP속도가 느려지고 대역폭이 커질 수 있기 때문에 <Image />를 사용해서 최적화 시키라는 뜻입니다.

 


 

다시 돌아와서 layout을 사용하기 위해서 아래와 같은 내용을 추가시켰습니다.

$ npx @next/codemod next-image-to-legacy-image .

위 내용으로 next/image 가져오기를 next/legacyy/image로 자동변경해준다고 나와있는데... 자동변경 안해주던뎅..

NextJS next/image version 13 바로가기

NextJS next/legacy/image에 관한 내용 바로가기

 

그래서 직접 그냥 변경해주었습니다.

// 변경전
import Image from 'next/image';

// 변경후
import Image from 'next/legacy/image';

위처럼 변경하고나니 아래처럼 하이픈이 제거되었습니다.

 

반응형
반응형

next-dev.js?3515:20 Warning: Cannot update a component (`Side`) while rendering a different component (`Main`). To locate the bad setState() call inside `Main`, follow the stack trace as described in

 

NextJS를 작성중 위와 같은 에러가 발생했습니다.

Main을 렌더링하는 동안 Side를 업데이트할 수 없다는 내용 같습니다. 

:: 부모 컴포넌트가 렌더링 될 때, 부모 컴포넌트 안의 자식 컴포넌트에 상태 업데이트를 할당할 때 일어난다고 합니다.

( 이 에러의 이상한 점은 첫 렌더링에서는 버그가 발생하지 않고 라우터를 이동할 때 생겨서 당황했습니다. )

 

여러 글을 읽어보니 redux를 사용하기 위해 사용했던 useDispatch를 렌더링중에 실행되는 useMemo에서 호출해서 문제가 생겼던 것 같습니다.

그래서 문제점을 해결하기 위해 화면에 렌더링이 완료된 이후에 수행되는 useEffect를 사용을 했더니 문제점이 해결되었습니다.

 

/* 전 */
const dispatch = useAppDispatch();

const test = useMemo(() => dispatch(), [])

/* 후 */
const dispatch = useAppDispatch();

useEffect(() => {
    dispatch()
}, [])

 

반응형
반응형

getStaticProps VS getServerSideProps

 

getStaticProps ( SSG: Static Site Generation )

getStaticProps는 최초 빌드 시에 딱 한번만 호출이 됩니다. 즉, 최초 빌드 시 빌드되는 값이 추후에 수정되는 일이 없는 경우에 사용하기 좋습니다. 

장점은 호출 시 마다 매번 fetch를 하지 않기 때문에 성능면에서는 getServerSideProps보다 좋습니다.

 

export async function getStaticProps() {

    return {
        props: {}
    }
}

 

getServerSideProps ( SSR: Server Side Rendering )

getServerSideProps는 getStaticProps와 다르게 요청이 들어올 때마다 호출되며, 그 때마다 사전 렌더링을 진행합니다.

이 경우, 요청 시마다 다시 호출하기 때문에 빌드 이후 자주 바뀌게 될 동적 데이터가 들어갈 때 사용하기 좋습니다.

 

export async function getServerSideProps() {

    return {
        props: {}
    }
}

getServerSideProps는 서버와 관련된 기능입니다.

getServerSideProps()안에 들어가는 코드는 어떤 코드를 쓰던지 서버에서 작동합니다.

이걸 이용해서 API Key를 숨기는것도 가능합니다. ( BackEnd에서 실행되기 때문입니다. )

 

호출은 _app.js의 component를 호출하고 pageProps에서 호출된다고 생각하면 됩니다.

 

Only absolute URL

getServerSideProps는 서버에서 작동하기 때문에 프론트엔드에서 실행할 때와 다르게 URL이 없기 때문에 fetch를 사용할 때 절대주소를 입력해주어야 합니다.

export async function getServerSideProps() {

    // TypeError: Only absolute URLs are supported
    const { results } = await ( await fetch(`http://localhost:3000/~`)).json();

    return {
        // props key 내부에는 원하는 데이터를 아무거나 넣을 수 있다. ( 무엇을 return하던지 props로써 page에게 주게된다. ex) Home())
        // 이 데이터는 pageProps를 통해 전달된다.
        props: {}
    }
}

 

반응형
반응형

next.config.js 란?

NextJS에서 커스텀 설정을 하기 위해 프로젝트 디렉터리의 루트폴더에 next.config.js or next.config.mjs 파일을 만들 수 있습니다.

이는 JSON파일이 아닌 NodeJS 모듈입니다.

NextJS 서버 및 빌드 단계에서 사용되며, 브라우저 빌드에는 포함되지 않습니다.

 

몇가지 기능들

 

Base Path

// next.config.js
module.exports = {
    basePath: "/docs"
}

// app.js
<Link href="/about">About으로 이동</Link>
<Image src="/docs/new.png" alt="이미지" />

 

위처럼 basePath를 적용시키면 라우터 이동시에 /about이 아닌 /docs/about으로 이동하게 됩니다.

Image는 위처럼 /docs를 추가해서 해주어야 이미지가 제대로 제공됩니다.

 

 

Rewrites

async rewrites() {
    return [
        {
            source: "/about",
            destination: "/"
        }
    ]
}

rewrites는 클라이언트 측 라우팅에 <Link href="/about">~</Link> 적용되며, 위처럼 재작성이 적용됩니다.

간단하게 말하면 source URL로 이동을 하면 destination이 실행됩니다.

예를 들어 긴 URL을 감추거나 API키를 감추거나 하는데 사용할 수 있습니다.

 

Redirects

module.exports = {
  async redirects() {
    return [
      {
        source: '/about',
        destination: '/',
        permanent: true,
      },
    ]
  },
}

redirects를 사용하면 들어오는 요청 경로를 다른 대상 경로로 리디렉션할 수 있습니다.

permanent는 boolean으로 설정할 수 있으며, true면 클라이언트 / 검색 엔진이 리디렉션을 영구적으로 캐싱하도록 지시하는 308 상태 코드를 사용하고, false면 일시적이며 캐시되지 않는 307 상태 코드를 사용합니다.

 

redirects은 source URL이 destination URL로 변경되는 것을 유저가 확인할 수 있지만, rewrites는 source URL만 유저가 확인할 수 있고, destination URL은 유저가 알 수 없습니다.

 

images

const nextConfig = {
  reactStrictMode: true,
  images: {
    domains: [
      "www.notion.so"
    ]
  }
}

remotePatterns와 맟찬가지로 도메인 구성을 사용하여 외부 이미지에 허용된 호스트 이름 목록을 제공할 수 있습니다.

간단하게 말하면 외부에서 이미지를 가져올 때, 외부 URL을 함부로 사용할 수 없기 때문에 next.config.js에서 사용할 수 있도록 도와준다고 생각하면 됩니다.

반응형
반응형

NextJS 시작하기 

NextJS를 시작하기 전에 ReactJS와 NextJS의 차이점을 알고 넘어가면 좋습니다.

 

Framework VS Library

ReactJS: 라이브러리입니다.

NextJS:  ReactJS의 프레임워크입니다.

 

  • Framework
    원하는 기능 구현에 집중하여 개발할 수 있도록 일정한 형태와 필요한 기능들을 갖추고 있는 뼈대를 의미합니다.
    애플리케이션 개발 시 필수적인 코드, 알고리즘, DB연동과 같은 기능들을 위해 어느 정도 뼈대를 제공하며 이러한 뼈대 위에서 사용자는 코드를 작성하여 애플리케이션을 개발합니다. 앱 / 서버등의 구동, 메모리 관리, 이벤트 루프 등의 공통된 부분으 프레임워크가 관리해주며, 사용자는 플레임워크가 정해준 방식대로 구현하면 됩니다.

  • Library
    소프트웨어를 개발할 때 컴퓨터 프로그램이 사용하는 비휘발성 자원들의 모임입니다. 즉 특정 기능을 모아둔 코드, 함수들의 집합이며 코드 작성 시 활용 가능한 도구들을 의미합니다.

CSR VS SSR

ReactJS: create-react-app로 만든 ReactJS는 CSR( Client Side Rendering )입니다.

NextJS: create-next-app로 만든 NextJS는 SSR( Serveer Side Rendering )입니다.

 

위 둘의 차이점은 유저가 브라우저에서 보는 화면인 UI를 어디서 만들어 주느냐에 따라 구분됩니다.

CSR은 클라이언트에서, SSR은 서버에서 화면을 구성합니다.

 

CSR의 동작 방식

유저, 서버, 브라우저 각각의 입장을 나누어 이해합니다. ( 브라우저 = 유저와 앱의 연결로 )

  1. 유저가 브라우저를 통해 앱에 접속합니다.
  2. 앱은 브라우저에게 Javascript의 정보가 들어있는 빈 HTML문서를 전달합니다. ( 브라우저에게 Javascript파일을 전달합니다. )
  3. 브라우저는 Javascript파일을 다운로드하고 동시에 유저는 빈 화면을 보게됩니다. ( 접속에 대한 응답입니다. )
  4. 브라우저에서 Javascript파일의 다운로드가 끝나면 React Code가 있는 Javascript파일을 실행합니다.
  5. 브라우저에 있는 React Code가 UI를 렌더링하니다. ( 동적 렌더링 )
  6. 유저는 앱이 보여주고자 했던 화면을 보게 됩니다.

즉, 브라우저가 Javascript코드를 갖고있지 않거나, 요청중인 상태라면 UI를 구성할 수 없으며, 유저는 빈화면을 보게됩니다.

리액트가 실행되기 전까지 유저 화면에 아무것도 보이지 않는 것입니다. 이렇게 클라이언트 측에서 UI를 빌드하는 것을 CSR방식이라고 합니다.

 

CSR의 장점

  • 초기 로드에 성공하면 이후 렌더링이 빠릅니다.
  • 클라이언트에서 처리하기 때문에 서버에 요청할 것이 적습니다. ( 서버의 부담이 적습니다. )

CSR의 단점

  • SEO( Search Engine Optimization )에 좋지 않습니다. ( 초기 HTML파일이 비어있기 때문에 데이터 수집에 어려움이 있습니다. 검색엔진.. )
  • 초기 로드가 오래 걸립니다.
  • 외부 라이브러리에 의존할 경우가 많습니다.

 

SSR 동작 방식

유저, 서버, 브라우저 각각의 입장을 나누어 이해합니다. ( 브라우저 = 유저와 앱의 연결로 )

  1. 유저가 브라우저를 통해 앱에 접속합니다.
  2. 서버에서 React를 실행시켜줍니다. ( React는 UI를 렌더링합니다. ) 
  3. 렌더링된 결과를 통해 브라우저에게 HTML을 제공합니다. ( 이 때, 유저는 앱의 초기화면을 보게됩니다. [ 접속에 대한 응답 ] )
  4. 이후, 브라우저는 React Code가 있는 Javascript파일을 다운받고 실행시킵니다. ( 이때부터 일반적인 React앱과 같이 CSR의 동작을 하게되며 이 과정을 Hydration이라고합니다. )
    Hydration: React Code가 브라우저에 이미 존재하는 HTML과 동기화하여 앱이 동적으로 상호작용할 수 있도록하는 과정입니다.
    즉, 서버에서 모든 UI를 구성한 후, 유저에게 응답해 화면을 보여주는 방식으로, 화면이 Pre-Rendering되어 유저는 인터넷 속도에 상관없이 화면에 무언가 나오는 것을 볼 수 있습니다. 이렇게 서버 측에서 UI를 렌더링하는 것을 SSR 동작 방식이라고 합니다.

 

SSR의 장점

  • SEO ( Search Engine Optimization )에 좋습니다. ( HTML파일에 모든 정보가 포함되기 때문입니다. )
  • 초기 로딩이 빠릅니다.
  • 클라이언트의 부담이 CSR의 비해 적습니다.

SSR의 단점

  • 서버에서 전체 앱을 미리 렌더링하기 때문에 컴포넌트 로딩이 오래 걸리면 유저는 빈 화면을 보게됩니다.
  • 모든 요청에 대해 필요한 부분을 수정하는 것이 아닌 새로운 HTML페이지를 내려주기 때문에 속도 저하나 새로고침이 발생합니다.
  • 페이지를 요청할 때마다 새로고침되어서 UX가 다소 떨어집니다.

 

NextJS의 특징

코드 스플리팅

일반적인 리액트 싱글페이지에서는 초기 렌더링때 모든 컴포넌트를 내려받습니다. 하지만 규모가 커지고, 용량이 커지면 로딩속도가 지연될 수 있는 문제점이 있습니다.

NextJS는 이러한 문제점을 개선해서 필요에 따라 파일을 불러올 수 있도록 여러 개의 파일을 분리하는 코드 스플리팅을 사용하였습니다. 폴더구조에 pages폴더 안에 라우트들이 들어가며, Components폴더에는 React Component들이 들어가게 됩니다.

ex ) 브라우저가 실행되고, 사용자가 접속을 하면 첫 페이지는 index page만 불러오게 되고, 그 이후에 다른 페이지로 넘어갔을 때는 해당 페이지만 불러오게 됩니다.

 

파일기반 내비게이션 기능

ReactJS에서는 루트를 위해서 react-router-dom이라는 라이브러리를 사용하여 라우팅 설정을 해주어야 합니다.

그로 인해 페이지의 경로에 대해 직접 설정을 해주어야 하지만, NextJS는 파일 시스템 기반 라우팅을 사용합니다. 폴더의 경로에 따라 페이지의 경로가 설정되어 구축이 빠르고 관리가 편리한 장점이 있습니다.

 

Hot Code Reloading을 지원하는 개발 환경

NextJS 개발 환경에서는 코드 변경 사항이 저장되면 응용 프로그램을 자동으로 다시 로드합니다. 개발 모드일 때 소스코드를 저장하면 브라우저 오른쪽 하단에 애니메이션 아이콘이 생기며, 이는 NextJS가 응용 프로그램을 컴파일하고 있다는 것을 의미합니다

 

styled-jsx 지원

NextJS는 자체 CSS-In-JS인 styled-jsx를 지원합니다. 기본적으로 제공하는 기능이기 때문에 스타일을 서버 사이드 렌더링 하기 위한 설정이 필요하지 않습니다.

 

반응형

+ Recent posts