[모던리액트]- 4장 (2) 서버 사이드 렌더링을 위한 리액트 API

nais·2024년 11월 27일
0

모던리액트

목록 보기
5/6
post-thumbnail

리액트는 프론트엔드 라이브러리로 브라우저 자바스크립트 환경의 렌더링과 동시에 리액트 애플리케이션 서버에서 렌더링 할 수 있는 API를 제공한다 18버전 이전의 기본 적인 함수을 모던리액ㅌ를 기반으로 정리하며 이외에 18버전 이후에는 어떤 API가 있는지 학습해보고자 한다!

React 18 이전의 SSR API

4.2.1 renderToString

  • 인수로 넘겨 받은 리액트 컴포넌트를 렌더링해 HTML 문자열로 반환하는 함수
  • 서버사이드 렌더링 구현 시 최초 페이지를 HTML로 구현하는 역할을 함
  • useEffect나 이벤트 핸들러는 결과물에 포함되지 않는다 이는 이 함수가 클라이언트에서 실행되는 자바스크립트 코드를 포함시키거나 렌더링하는 역할은 하지 않는다
  • React-specific 속성을 포함한다

deep dive! 📌
1.React-specific 속성의 역할
(1) Hydration 을 위한 DOM 식별

  • 서버에서 생성된 HTM을 클라이언트에서 재활용 하려면 React가 DOM 구조를 정확히 이해 필요 이 속성을 통해 서버에서 생성된 DOM 과 React 의 가상 DOM (virtual DOM)을 연결
    (1) 효율적인 업데이트 지원
  • 초기 Hydration 과정에서는 React는 서버에서 렌더링 된 HTML을 수정하지 않고 유지 하려고 시도함 React-specific 속성을 사용해 DOM 과 React 상태 간의 동기화 빠르게 수행
    2.주요속성
    (1) data-reactroot
  • 리액트 컴포넌트의 루트 엘리먼트를 식별, 이는 이후 자바스크립트를 실행하기 위한 hydrate 함수에서 루트를 식별하는 기준점
  • Hydration 시 React가 이 루트를 기반으로 DOM 을 다시 구성한다
    (2) data-reactid(React 15 및 이전 버전에 사용)
  • React가 DOM 요소를 식별, 업데이트 효율성 높이기 위해 추가한 내부 ID
  • React 16이후부터는 더 이상 사용되지 않음
    (3) __reactProps$
  • React 18에서는 SSR 및 Hydration에서 이벤트 핸들러와 같은 속성을 관리하기 위해 내부적으로 사용되는 속성
  • 이 속성은 Hydration이 끝난 후 사라질 수 있음

4.2.2 renderToSaticMarkup

  • renderToString 과 매우 유사하고 이 역시 리액트 컴포넌트를 기준으로 HTML 문자열을 만든다는 점에서 동일
  • 차이점으로는 data-reactroot와 같은 리액트에서만 사용하는 추가적인 DOM 속성을 만들지 않는다
  • 때문에 결과물인 HTML의 크기를 약간이라도 줄일 수 있다는 장점가지고 있다
  • hydrate를 수행하지 않는다는 가정하에 순수한 HTML만 반환
  • 리액트의 이벤트 리스너가 필요 없는 완전 순수한 블로그 글이나 약관 정보 등이 알맞다

4.2.3 renderToNodeStream

  • renderToNodeStream 은 브라우저에서 사용하는 것이 완전히 불가능하다.
  • 이 함수의 결과물은 Node.js 의 ReadableStream 이다. 이는 utf-8로 인코딩된 바이트 스트림 Node.js , Deno, Bun 과 같은 서버 환경에서만 사용할 수 있다 (브라우저가 원하는 결과물인 string 을 얻기 위해서는 추가적인 처리 필요)
  • 스트림은 큰 데이터를 다룰 때 데이터를 청크(chunk,작은 단위) 로 분할해 조금씩 가져오는 방식을 의미
  • renderToString 을 생성하면 문자열을 한번에 메모리에 올리고 수행, 서버에서 부담될 수 있다
  • 스트림을 활용하면 큰 크기의 데이터를 청크 단위로 순차적으로 처리할 수 있는 장점
  • 알려진 리액트 서버 사이드 렌더링 프레임 워크는renderToNodeStream 을 채택

4.2.4 renderToStaticNodeStream

  • renderToNodeStream과 제공하는 결과물은 동일하다
  • renderToSaticMarkup과 마찬가지로 리액트 자바스크립트에 필요한 리액트 속성이 제공되지 않는다
  • 마찬가지로 hydrate를 할 필요가 없는 순수 HTML 결과물이 필요할 때 사용

4.2.5 hydrate

  • hydrate 함수는 앞서 살펴본 rederToString 과 rederToNodeStream 으로 생성된 HTML 콘텐츠에 자바스크립트 핸들러나 이벤트를 붙이는 역할
  • hydrate 가 정적으로 생성된 HTML 에 이벤트와 핸들러를 붙여 완전한 결과물을 만든다

    비슷하게 브라우저에서만 사용되는 메서드인 render 가 있다
    1) 컴포넌트와 HTML 요소를 인수로 받는다 이렇게 인수 받은 정보를 바탕으로 HTML의 요소에 해당 컴포넌트를 렌더링하며, 이벤트 핸들러를 붙이는 작업까지 한번에 수행
    2) 클라이언트에서만 실행되는,렌더링과 이벤트 핸들러 추가 등 리액트 기반으로 한 온전한 웹페이지를 만드는데 필요한 모든 작업 수행

React 18 이후의 SSR API

renderToPipeableStream

  • React 컴포넌트를 HTML을 ReadableStream 으로 생성하며 브라우저와 서버에서 모두 사용가능
  • Node.js 환경에서 사용 가능하다
  • 스트리밍 도중 추가 데이터를 주입이 가능
  • Suspense 와 함께 작동
  • HTML을 스트리밍으로 클라이언트로 전송 가능
  • 초기 콘텐츠를 빠르게 렌더링하기에 동적인 애플리케이션 및 성능 최적화가 필요한 경우 알맞다
import React from "react";
import { renderToPipeableStream } from "react-dom/server";
import { Readable } from "stream";

function App() {
  return <div>Streaming Content</div>;
}

const { pipe } = renderToPipeableStream(<App />, {
  onShellReady() {
    console.log("HTML shell is ready!");
    // 스트림 데이터를 전송할 준비가 완료됨.
    pipe(process.stdout); // Node.js에서는 stdout으로 스트리밍 가능.
  },
  onError(err) {
    console.error("Error during SSR:", err);
  },
});

renderToReadableStream

  • React 컴포넌트를 Web Streams API 를 통해 스트리밍으로 렌더링
  • 브라우저와 Web Streams API 지원 서버에서 사용 가능
  • 클라이언트(브라우저) -서버 간 효율적인 데이터 전송 가능하기에 호환적인 스트리밍 렌더링이 가능
import React from "react";
import { renderToReadableStream } from "react-dom/server";

async function render() {
  const stream = await renderToReadableStream(<div>Hello, Readable Stream!</div>);
  const reader = stream.getReader();
  const result = await reader.read();
  console.log(new TextDecoder().decode(result.value));
}

render();

비교 정리

profile
왜가 디폴트값인 프론트엔드 개발자

0개의 댓글