공부 및 일상기록

[NextJS] NextJS의 v12와 v13의 가장 큰 차이는? (feat : sever component) 본문

개발/Next JS

[NextJS] NextJS의 v12와 v13의 가장 큰 차이는? (feat : sever component)

낚시하고싶어요 2023. 9. 19. 01:09

NextJS의 v12와 v13의 가장 큰 차이점 바로 "Server Component"

v13버전에서 pages 폴더를 대신하여 app 폴더를 사용하게 되었다. 그리고 app 폴더 내부에서는 모든 컴포넌트가 Server Component로 동작하게 된다. 만약 app 폴더 내부에서 클라이언트 컴포넌트를 사용하려면 파일의 최상단에 'use client' 라고 명시해야 한다.

 

그렇다면 Server Component란?

서버컴포넌트(Server Component)는 2020년 12월에 소개된 React 18의 기능 중 하나이다.

 

기존 리액트의 data fetching에 대해 살펴보면 다음과 같다.

function Todo({ userId }) {
  return (
    <UserDetails userId={userId}>
        <TodoList userId={userId}/>
        <CompletedTodoList userId={userId}/>
    </UserDetails>
  );
}

만약 부모 컴포넌트 (UserDetail) 와 자식 컴포넌트 (TodoList, CompletedTodoList)가 모두 다른 유저 정보가 필요한 위와 같은 프로젝트가 있다고 가정해본다.

 

그럼 다양한 방법이 있겠지만 보통 두가지 정도의 선택지로 갈리게 된다.

 

1. 상위에서 api를 호출하여 자식으로 내려준다.

2. 각 자식 컴포넌트에서 필요한 api를 직접 호출한다.

 

첫 번째 방법의 장점은 데이터 흐름이 명확해지고 일관된 처리가 용이해진다. 또한 여러 자식 컴포넌트에서 동일한 데이터가 쓰이게 되는 경우 중복된 API호출을 피할 수 있다.

하지만 상위에서 하위로 데이터를 전달해야 하므로 복잡한 데이터 구조나 다수의 자식 컴포넌트가 있는 경우 코드가 복잡해 질 우려가 있다.

 

두 번째 방법의 장점은 각 컴포넌트가 독립된 데이터를 가져오기 때문에 컴포넌트간의 의존성이 낮아진다. 또한 자식컴포넌트가 자신의 데이터 요청을 관리하므로 컴포넌트 간 역할이 명확해진다.

하지만 동일한 데이터를 다른 여러 자식컴포넌트에서 필요로 할 경우, 중복된 api 호출이 발생할 수 있고, 이는 성능 문제를 야기할 수 있다. 또한 데이터 요청 및 관리가 분산되어 데이터의 일관성을 유지하기 힘들고, 복잡한 데이터 흐름때문에 유지보수가 어려울 수 있다. 그리고 부모 컴포넌트가 데이터를 받아오기 시작하기 전까지 자식 컴포넌트의 렌더링과 api호출도 지연될 수 있어서 사용자 경험을 저하시킬 것이다.

 

이러한 문제를 해결하기 위해 Server Component를 도입하게 된 것이다.

 

서버 컴포넌트를 사용하면 컴포넌트 렌더링을 클라이언트가 아닌 서버에서 수행하게 된다. 따라서 api를 통한 데이터 요청의 latency(데이터 요청시 송신측에서 수신측으로 전송되는 동안 소요되는 시간) 을 줄일 수 있고, 클라이언트에서 연속된 api 호출을 최적화 하여 성능과 사용자 경험을 향상시킬 수 있다.

 

더 자세한 내용은 다음에 제대로 조사하여 작성하도록 하고...  이제 NextJS의 v12와 v13에서의 차이에 대해 알아보자


그래서 서버 컴포넌트를 사용한 NextJS v13은 뭐가 달라진건데?

 

v12 까지는 페이지 단위로 렌더링 방식을 정했다.

1. getStaticProps 함수를 사용하여 빌드 시점에 페이지를 렌더링 하는 SSG (Static Site Generation)

2. getStaticProps 함수에 revalidate 시간을 추가하여 빌드 시점에 페이지를 렌더링 한 후, 설정한 시간마다 새로 렌더링 하는 ISR (Incremental Static Regeneration)

3. getServerSideProps 함수를 이용해 서버에서 요청을 받았을 때 렌더링하는 SSR (Server Side Rendering)

 

 

v13 부터는 페이지 단위가 아닌 컴포넌트 단위로 렌더링 방식을 정한다.

출처 : https://www.plasmic.app/blog/how-react-server-components-work

한 페이지 안에 위 그림과 같이 각 컴포넌트마다 어떤것은 서버 컴포넌트, 어떤것은 클라이언트 컴포넌트로 구성하여 각 상황에 맞게 효율적으로 구성하게 되는 것이다. 

 

프로젝트의 요구마다 어떻게 구성할지는 다르지만, 일반적인 가이드는 다음과 같다.

 

1. 서버 컴포넌트로 구성해야 하는 컴포넌트

  • 필요한 데이터를 서버에서 가져와야 하는 경우 : ex) 초기 페이지 로딩 시, 필요한 데이터를 서버에서 렌더링 시점에 가져와야 하는 경우
  • 사용자마다 다른 데이터가 필요한 경우 : 각 사용자에게 다른 데이터가 필요하거나 인증된 사용자에게만 특정 데이터를 제공해야하는 경우 
    • ex 1) 사용자마다 다른 데이터가 필요한 경우 : 온라인 쇼핑몰에서 사용자 마다 관심 상품이 다를 수 있으므로 사용자의 관심 품목을 서버에서 가져와 페이지를 렌더링
    • ex 2) 인증된 사용자에게 특정 데이터 제공 : 소셜미디어를 생각해보면 사용자 중 일부는 로그인하여 개인 메시지를 볼 수 있지만 로그인 하지 않은 사용자는 메시지가 표시되지 않아야 함. 이런 경우 서버컴포넌트에서 로그인 상태를 확인 후 알맞은 데이터를 서버에서 가져와 렌더링 진행 ==> 보안과 데이터 보호가 유지됨
  • SEO (Search Engine Optimization) 가 중요한 페이지 : SEO가 중요하다면 서버 컴포넌트를 사용하여 검색엔진에 최적화 된 콘텐츠를 제공할 수 있음

2. 클라이언트 컴포넌트로 구성해야 하는 컴포넌트

  • 실시간 업데이트 및 상호작용이 필요한 경우 : 사용자와 상호작용하며 동적으로 업데이트되는 부분은 클라이언트 컴포넌트로 구성한다. ex) 사용자가 폼을 작성하거나 실시간 채팅을 사용하는 부분
  • 데이터를 브라우저에서 가져오는 것이 더 효율적인 경우 : 페이지 로딩 후에도 추가 데이터가 필요하거나 사용자 인터랙션에 따라 데이터를 동적으로 로드해야 할 때 클라이언트 컴포넌트를 사용
  • 서버에서 렌더링하기 어려운 복잡한 UI : 복잡한 UI 컴포넌트는 서버 부하를 증가시킬 수 있으며 이에 따라 초기 로딩 시간이 너무 길어질 수 있다. 

따라서 간단하게 생각했을때, 사용자와 상호작용을 하여 실시간으로 데이터가 바뀐다면 클라이언트 컴포넌트, 데이터를 미리 서버에서 받아올 수 있으며 보안이 중요하다면 서버 컴포넌트로 작성할 수 있다. (하지만 어디까지나 일반적인 경우이고, 프로젝트마다 요구하는 바가 무엇인지 잘 따져보아야 한다.)

'개발 > Next JS' 카테고리의 다른 글

next 블로그에 SEO삽입  (1) 2023.04.20
[Next.js] 동적 라우팅 및 router.query  (0) 2023.02.13