Frontend

NextJS 14의 렌더링 방식 (Hydration)🍀

코구리 2024. 8. 15. 18:11

NextJS는 React의 프레임워크로, 기본적으로 CSR(클라이언트 사이드 렌더링)을 지원하는 리액트와는 다르게 SSR(서버 사이드 렌더링)을 지원하기 때문에 검색엔진 최적화에 유리하고, 초기 렌더링 속도가 빠르다. 그밖에도 서버 데이터 패칭,캐싱 등 최적화를 너무 쉽게 할 수 있어서 성능을 대폭 향상시킬 수 있다.
오늘은 CSR과 SSR을 자세히 비교해보고 NextJS 14버전에서 지원하는 Hydration까지 알아보자.
 

1. CSR과 SSR

1) CSR

CSR(클라이언트 사이드 렌더링)은 클라이언트에서 모든 렌더링을 담당하는 것을 말한다. 리액트는 기본적으로 CSR을 지원한다. 따라서 초기 렌더링 시에 자바스크립트를 다운받고 UI를 로드한다.
 
장점

  • 부드럽고 빠른 화면 전환 (깜빡임 이슈 없음)
  • 서버에 부담 적음

단점

  • 초기 렌더링 시에 모든 리소스를 다운받아야 하기 때문에 시간이 오래 걸림
  • HTML이 단 하나로, 메타 태그가 하나 뿐이기 때문에 검색엔진에 불리함

 

2) SSR

SSR(서버 사이드 렌더링)은 서버에서 렌더링을 수행하는 것을 말한다. 즉 서버에서 HTML을 만들어서 전달해준다. 
 
장점

  • 현재 접근하는 페이지의 HTML만 전달받기 때문에 초기 렌더링 시간이 빠름
  • 각 페이지마다 HTML이 있기 때문에 검색엔진에 유리함

단점

  • 화면 전환 시마다 새로운 HTML을 가져오기 때문에 깜빡임 이슈 있음
  • 서버에 비교적 부담이 됨 

 
NextJS는 기본적으로 SSR을 지원하지만 SSR만의 단점을 보완하여 CSR의 장점과 SSR의 장점을 모두 가져가는 효자 프레임워크이다. 그래서 현재 세계에서 가장많은 기업에서 사용되는 기술이라고 한다.
아래에서 NextJS의 컴포넌트가 어떻게 동작하는지 자세히 알아보도록 하자.
 

2. 서버 컴포넌트

NextJS는 따로 명시해주지 않는 한 기본적으로 모든 컴포넌트가 서버 컴포넌트이다.
사용자가 페이지에 도달하면, 브라우저가 서버에 요청을 보내서 서버에서 렌더링을 하고 정적인 HTML을 브라우저에 전달한다.
정적이기 때문에 자바스크립트가 포함되지 않은 상태이다. 따라서 이벤트 리스너가 등록되어있지 않은 정적인 상태이다. 그래서 초기에 빠르게 페이지를 렌더링 할 수 있다.
 
NextJS에서 테스트용으로 서버 컴포넌트를 만들고 렌더링해보았다.

export default function TestHeader() {
  return (
    <div>
      <h1>This is a test page.</h1>
    </div>
  );
}

 
개발자도구의 소스 탭에서 명령어 실행 버튼 -> 자바스크립트를 검색해서 '자바스크립트 사용 중지'를 누르면 자바스크립트 없이 렌더링을 해볼 수 있다.

 
위 사진과 같이 자바스크립트가 실행되지 않았음에도 초기 페이지가 잘 렌더링 된 것을 알 수 있다.
 

3. Hydration

하지만 모든 컴포넌트는 위 예시와 같이 정적이지는 않다. 아래와 같이 사용자가 버튼을 누르면 버튼 내부의 카운트가 올라가는 등 사용자와의 인터렉션이 필요한 컴포넌트가 정말 많다.
이렇게 useState를 사용하는 등의 동적인 컴포넌트는 반드시 클라이언트 컴포넌트로 만들어줘야 한다.
'use client'를 명시하면 클라이언트 컴포넌트가 된다. 참고로 리액트 훅을 사용할 때는 use client를 항상 명시해줘야 한다.

'use client';

import { useState } from 'react';

export default function TestBtn() {
  const [count, setCount] = useState(0);
  const addCount = () => {
    setCount(count + 1);
  };

  return <button onClick={addCount}>{count}</button>;
}

 
클라이언트 컴포넌트는 정적인 HTML이 전달된 이후에 아주 빠른 시간 내에 자바스크립트를 다운받는다. 위의 경우 버튼에 이벤트 리스너를 연결한다. 이렇게 해서 리액트에서 사용하는 것처럼 부드러운 인터렉션을 만들 수 있다.
이 과정을 Hydration이라고 한다. 즉 단순한 HTML을 리액트 앱으로 초기화하는 작업을 말한다.
 

 
아까와 같이 자바스크립트 사용 중지 후 새로고침을 하게 되면 버튼은 이벤트 리스너가 연결되지 않은 정적인 컴포넌트 상태로 유지되기 때문에 버튼을 눌러도 카운트가 올라가지 않는다.
 
이렇게 하나의 페이지 내에 서버 컴포넌트와 클라이언트 컴포넌트를 필요에 맞게 섞어서 사용함으로써 꼭 필요한 JS만 로드할 수 있다. 따라서 렌더링 시간이 줄어들기 때문에 성능 최적화를 쉽게 할 수 있는 것이다.
 
니꼬쌤 강의를 들으면서 넥스트를 공부해보고 있는데 넘 좋은 기술인 것 같고 재밌다. 프로젝트에서 얼른 사용해보고 싶다.
그리고 무엇보다 설명을 진짜 잘해주셔서 너무 만족하면서 들었다. 다른 것도 니꼬쌤 강의로 듣고 싶다.
넥스트 공부해보실 분들은 노마드코더 강의 추천합니다👍
 
https://nomadcoders.co/nextjs-for-beginners/lectures/4696

All Courses – 노마드 코더 Nomad Coders

초급부터 고급까지! 니꼬쌤과 함께 풀스택으로 성장하세요!

nomadcoders.co