Published On

Next.js의 렌더링 과정


Next.js는 서버 컴포넌트클라이언트 컴포넌트를 조합하여 효율적인 렌더링을 수행합니다.

서버 컴포넌트와 클라이언트 컴포넌트의 렌더링 과정, 최적화 원리의 차이점을 단계별로 설명하겠습니다.


컴포넌트란?

React에서 컴포넌트는 데이터를 받아 JSX를 반환하는 JavaScript 함수입니다.

Next.js는 서버 컴포넌트라는 개념을 추가하여, 다음과 같은 컴포넌트로 구분합니다.

  • 클라이언트 컴포넌트:

    • 브라우저에서 실행되며 UI 인터랙션과 상태 관리를 담당합니다.

    • 이벤트 핸들러와 같은 클라이언트 전용 코드를 포함합니다.

  • 서버 컴포넌트:

    • 서버에서 실행되며, 클라이언트에 최적화된 HTML과 데이터를 제공합니다.
    • 클라이언트 전용 코드(예: 이벤트 핸들러)는 포함되지 않습니다.

Next.js를 활용하면 쉽게 서버 컴포넌트와 클라이언트 컴포넌트를 명확히 구분하여, 렌더링 성능을 최적화할 수 있습니다.


컴포넌트의 렌더링 과정

React에서 JSX는 JavaScript 객체(React.Element)로 변환됩니다.

이를 기반으로 React는 가상 DOM(Virtual DOM)을 생성하고, 효율적으로 UI를 업데이트합니다.

Next.js는 이 과정을 서버와 클라이언트의 역할 분담을 통해 최적화합니다.

  • React 컴포넌트의 렌더링은 다음 단계로 진행됩니다.
  1. JSX 호출: JSX 코드가 작성됩니다.
  2. Babel 변환: JSX가 JavaScript 코드로 변환됩니다.
  3. React.Element 생성: 변환된 코드가 React.createElement 호출로 객체화됩니다.
  4. Fiber 생성: React는 Fiber 트리를 생성해 컴포넌트 상태를 관리합니다.
  5. Virtual DOM 업데이트: 가상 DOM에서 변경 사항을 추적합니다.
  6. 실제 DOM 반영: 변경된 부분만 실제 DOM에 적용합니다.

단계React.Element의 역할Fiber의 역할
컴포넌트 생성JSX 코드에서 React.createElement를 통해 React.Element 객체가 생성React.Element를 바탕으로 Fiber 노드가 생성
렌더링 전Virtual DOM에서 컴포넌트 구조를 정의컴포넌트의 렌더링 상태를 추적하고 관리
렌더링 후Fiber 트리를 통해 Virtual DOM과 실제 DOM 간의 변경 사항을 효율적으로 관리변경된 부분만 DOM에 적용하도록 최적화

Fiber

React 16부터 도입된 Fiber는 가상 DOM의 확장된 구조로, 업데이트를 효율적으로 관리하는 역할을 합니다.

Fiber의 주요 특징

  • Fiber node:
    • React 내부에서 각 컴포넌트를 표현하는 기본 단위입니다.
    • React Element의 정보를 포함하며, 컴포넌트 트리를 구성하고 변경 사항을 추적합니다.
    • Fiber 트리를 기반으로 Virtual DOM과 실제 DOM 간의 업데이트를 효율적으로 관리합니다.
    • 성능 최적화를 위해 컴포넌트 구조를 트리 형태로 유지합니다.

Fiber는 컴포넌트의 상태를 지속적으로 추적하며, 업데이트 효율성을 극대화합니다.


서버 컴포넌트

서버 컴포넌트는 Next.js의 Server-Side Rendering(SSR)을 더욱 최적화한 방식으로, 브라우저 대신 서버에서 실행됩니다.

클라이언트 컴포넌트와는 다음과 같은 차이가 있습니다.

구분서버 컴포넌트클라이언트 컴포넌트
실행 위치서버브라우저
초기 렌더링서버에서 HTML 및 데이터를 미리 생성클라이언트에서 상태와 이벤트 처리
역할데이터 페칭 및 SSR 최적화UI 인터랙션, 상태 관리

1. DOM

DOM은 브라우저가 화면에 렌더링하는 실제 HTML 요소를 나타냅니다.

{
  "nodeName": "DIV",
  "nodeType": 1,
  "attributes": {
    "id": { "name": "id", "value": "root" }
  },
  "childNodes": [
    {
      "nodeName": "H1",
      "nodeType": 1,
      "attributes": {},
      "childNodes": [
        {
          "nodeName": "#text",
          "nodeType": 3,
          "nodeValue": "Hello, World!"
        }
      ]
    }
  ]
}

2. React.Element

React.Element는 JSX 코드가 변환된 JavaScript 객체입니다.

const element = {
  type: "h1",
  props: {
    children: "Hello, World!",
  },
  key: null,
  ref: null,
};

3. Fiber

Fiber는 React의 렌더링 상태와 Virtual DOM 간의 연결을 관리하는 데이터 구조입니다.

const fiberNode = {
  tag: "HostComponent", // 컴포넌트 유형 (예: 함수형, 클래스형 등)
  type: "h1", // React.Element의 타입
  stateNode: <h1>Hello, World!</h1>, // 실제 DOM 노드
  child: null, // 첫 번째 자식 Fiber
  sibling: null, // 형제 Fiber
  return: parentFiber, // 부모 Fiber
  alternate: previousFiber, // 이전 Fiber 트리
};

Next.js의 렌더링 과정은 DOM, React.Element, Fiber가 각자 다른 역할을 수행하면서 최적화됩니다.

이를 통해 초기 로드 속도와 동적 업데이트 성능을 극대화할 수 있습니다.


이전 포스트

React hooks - useState

다음 포스트

React hooks - useRef