[React] react + ssr

do_large·2021년 12월 26일
2

React

목록 보기
11/11

React를 실행시키면 브라우저에 index.html을 보내는데, 이 html은 비어있고, js코드로 화면을 그린다.
React에서 컴포넌트에 html처럼 생긴 코드를 작성하지만 이는 jsx문법이고, 리액트에서 실제로는 createElement라는 메서드를 통해 그려진다.

그래서 react로 작성된 코드는 브라우저가 js파일을 받아 직접 렌더링과정을 거치기때문에 초기 렌더링시간이 오래 걸린다고하는것이다.(아마..?)

그래서 react는 csr방식이라고 하는것이다.

그런데 react를 ssr처럼 동작하게 할수있는 방법을 찾아보던 중 아래와 같은 방법도 있다는 것을 발견했다.(사실 next.js는 react + ssr 이기 때문에 ssr처럼 만들고싶으면 그냥 next를 써라)


ReactDOMServer 를 통해 컴포넌트를 정적 마크업으로 렌더링할 수 있습니다.

다음 메서드는 서버와 브라우저 환경에서 사용할 수 있습니다.

  • renderToString()
  • renderToStaticMarkup()

아래 메서드는 서버에서만 사용할 수 있는 stream 패키지에 의존성이 있어 브라우저에서는 작동하지 않습니다.

  • renderToNodeStream()
  • renderToStaticNodeStream()

renderToString()

ReactDOMServer.renderToString(element)

  • 이 메서드는 react 엘리먼트의 초기 html을 렌더링한다.
  • React는 html문자열을 반환한다.
  • 빠른 페이지 로드를 위해 초기 요청시에 서버에서 html을 생성하여 마크업을 보내거나, 검색 엔진 최적화를 위해 검색엔진이 페이지를 크롤링할 수 있도록 하는데 사용할수있다.

이미 서버 렌더링 된 마크업이 있는 노드에서 ReactDOM.hydrate()를 호출하는 경우, React는 이를 보존하고 이벤트핸들러만 연결함

hydrate는 뭐야?
기존에 서버 사이드 렌더링된 결과물이 있을 경우 새로 렌더링하지 않고 기존에 존재하는 UI에 이벤트만 연동하여 애플리케이션을 초기 구동할 때 필요한 리소스를 최소화함으로써 성능을 최적화해줍니다.

renderToStaticMarkup()

ReactDOMServer.renderToString(element)

  • renderToString과 비슷하지만 data-reactroot와 같이 React에서 내부적으로 사용하는 추가적인 DOM 어트리뷰트를 만들지 않습니다.
  • 여분의 어트리뷰트를 제거함으로써 약간의 바이트를 절약할 수 있으므로 React를 간단한 정적 페이지 생성기로 사용하고 싶은 경우에 유용합니다.

renderToString 예제

우선 react + ssr 의 순서를 보면

  1. react 프로젝트를 빌드한다.
  2. 빌드 결과물을 정적 파일로 서버에서 제공하되
  3. 서버에서 서빙할 때, renderToString으로 React 엘리먼트의 초기 HTML을 렌더링하고 그 내용물을 hydrate 하면된다.

서버의 코드를 보면 노드로 되어있는데, 스프링으로 할수있는 방법을 찾아야할것같다.

암튼 아래의 코드를 보면 renderToString메서드에 보여주고자 하는 엘리먼트를 넣어준다.

import React from "react";
import { renderToString } from "react-dom/server";
import express from "express";
import App from "../src/App";

const app = express();
const PORT = 3005;

app.get("/", (req, res) => {
  res.send(`
      <!DOCTYPE html>
      <html lang="en">
        <head>
          <title>React App</title>
        </head>
        <body>
          <div id="root">${renderToString(<App />)}</div>
          <div>hello from server side</div>
        </body>
      </html>
  `);
});

app.listen(PORT, () => console.log(`http://localhost:${PORT}`));

그리고 클라이언트에서는 hydrate를 해준다.

ReactDOM.hydrate(<App />, document.getElementById("root"));

👇🏻  아래 링크로 들어가보면 스프링으로 구현한 예시를 볼수있다.

Spring Boot & Nashorn으로 SSR [BE]

ReactDOMServer - React

React SSR : ReactDOMServer.renderToString, hydrate

0개의 댓글