더이노베이터스

Streaming SSR

스트리밍 서버 사이드 렌더링 (Streaming Server-Side Rendering)

스트리밍 서버 사이드 렌더링(SSR)은 서버에서 렌더링된 애플리케이션을 클라이언트로 빠르게 전달하는 방법 중 하나입니다. 일반적인 SSR 방식에서는 현재 탐색 중인 페이지에 필요한 모든 HTML을 한 번에 생성하여 클라이언트로 전송합니다. 하지만 스트리밍 SSR을 활용하면 이 HTML을 여러 개의 작은 청크(조각)로 나누어 점진적으로 전송할 수 있습니다.

Node.js의 스트림 기능을 활용하면 응답 객체(response object)로 데이터를 지속적으로 보낼 수 있습니다. 이렇게 하면 클라이언트는 HTML 데이터 일부를 받는 즉시 렌더링을 시작할 수 있어, **페이지가 상호작용(Interactive)이 가능해지는 시간(Time To Interactive, TTI)**을 크게 단축할 수 있습니다.


React의 스트리밍 렌더링 (renderToNodeStream)

React는 renderToNodeStream이라는 내장 메서드를 제공하여 스트리밍 방식의 SSR을 지원합니다. 이를 활용하면 애플리케이션을 작은 조각 단위로 클라이언트에 전송할 수 있으며, 클라이언트는 아직 데이터를 모두 받기 전에 화면을 먼저 렌더링할 수 있습니다.

이렇게 스트리밍 방식으로 받은 HTML을 React의 hydrate 메서드를 호출하여 이벤트 핸들러를 연결하면 UI를 정상적으로 상호작용할 수 있게 됩니다.

스트리밍 SSR의 장점

1. 더 빠른 페이지 렌더링

기존 renderToString을 활용한 SSR 방식에서는 모든 HTML을 생성한 후에야 클라이언트에 전송할 수 있었습니다.

하지만 renderToNodeStream을 활용하면 HTML을 작은 조각으로 나누어 클라이언트가 즉시 렌더링을 시작할 수 있습니다.

2. 네트워크 혼잡(Backpressure) 대응

스트리밍 방식은 네트워크 속도가 느려도 클라이언트가 받을 수 있는 만큼만 데이터를 보내고, 네트워크가 원활해지면 다시 전송을 재개합니다.

이렇게 하면 서버가 여러 요청을 동시에 처리할 수 있어 무거운 요청이 가벼운 요청을 방해하지 않습니다.

3. SEO 친화적

스트리밍 SSR은 검색 엔진 크롤러가 HTML을 차례로 받아서 분석할 수 있게 도와줍니다.

일반적인 CSR(Client-Side Rendering) 방식보다 SEO 성능이 뛰어납니다.


React의 스트리밍 관련 API

React 16에서 스트리밍 SSR을 위한 API가 추가되었습니다.

  • ReactDOMServer.renderToNodeStream(element) → 기존 renderToString과 동일하지만, 데이터를 Node.js 스트림 형식으로 반환하여 점진적 렌더링이 가능함.
  • ReactDOMServer.renderToStaticNodeStream(element)renderToStaticMarkup과 유사하지만 스트림 형식으로 HTML을 반환함. → 정적인 페이지를 렌더링하는 데 적합.

스트리밍 SSR의 한계

1. 코드 수정 필요

기존 SSR 코드에서 renderToString단순히 renderToNodeStream으로 변경하는 것만으로는 정상 동작하지 않을 수 있습니다.

특히, 서버 렌더링 시 문서의 <head> 태그에 스타일을 추가하는 라이브러리는 별도의 처리가 필요합니다.

2. 템플릿 렌더링 방식과 충돌 가능

예를 들어, 다음과 같은 코드에서는 renderToStringrenderToNodeStream으로 바로 대체할 수 없습니다.

javascript
복사편집
res.write("<!DOCTYPE html>");
res.write(renderToStaticMarkup(
  <html>
    <head><title>My Page</title></head>
    <body>
      <div id="content">
        { renderToString(<MyPage/>) }
      </div>
    </body>
  </html>
));

이 경우, 문서 템플릿을 먼저 렌더링한 후 특정 컴포넌트만 스트리밍하는 방식으로 수정해야 합니다.

렌더링 방식 비교

렌더링 방식이점 (Pros)단점 (Cons)언제 사용하면 좋을까?
서버 컴포넌트 (Server Components)– 서버에서 렌더링되어 클라이언트 JS 번들 크기 감소 – 데이터베이스, API 요청을 서버에서 직접 실행 가능 – 클라이언트 상태 관리 부담 감소– 클라이언트에서 상태 관리 및 이벤트 핸들링 불가 – 기존 React 프로젝트와 완전 호환되지 않을 수 있음– 데이터가 서버에서 자주 변경되며, 클라이언트에서 복잡한 상호작용이 필요하지 않은 경우 – Next.js 같은 프레임워크를 사용할 때
기본 SSR (Standard SSR, renderToString)– 초기 페이지 로드 시 SEO 최적화 가능 – 클라이언트에서 렌더링 전에 완전한 HTML을 제공하여 안정적인 첫 번째 렌더링 보장– HTML을 완전히 생성한 후 전송하므로 Time To First Byte(TTFB)가 느려짐 – 대규모 애플리케이션에서는 서버 부하 증가– 작은 규모의 SSR 프로젝트 – SEO가 중요한 랜딩 페이지
스트리밍 SSR (Streaming SSR, renderToPipeableStream)– TTFB 감소, 페이지 로딩 속도 향상 – 네트워크 상태에 따라 유연한 데이터 전송 – Suspense를 통해 중요 콘텐츠부터 순차적 렌더링 가능– 일부 브라우저 및 CDN이 스트리밍을 완전히 지원하지 않을 수도 있음 – 기존 SSR 방식보다 구현이 다소 복잡할 수 있음– 대규모 애플리케이션에서 사용자 경험 개선이 필요할 때 – 긴 목록이나 복잡한 UI가 포함된 페이지에서 최적화 필요할 때

어떤 방식을 선택해야 할까?

  • 정적인 SEO 페이지 (블로그, 마케팅 페이지)기본 SSR
  • 대량의 데이터를 처리하는 대시보드, SaaS 애플리케이션서버 컴포넌트 + 스트리밍 SSR
  • 페이지 로딩 속도가 중요한 웹앱 (뉴스 사이트, 전자상거래 플랫폼)스트리밍 SSR
  • 사용자 인터랙션이 많은 애플리케이션 (SNS, 웹 메신저)클라이언트 사이드 렌더링(CSR) + 서버 컴포넌트 조합

결론

React 19에서는 다양한 서버 렌더링 기법을 활용하여 애플리케이션의 성능을 최적화할 수 있습니다. 서버 컴포넌트는 데이터 페칭을 최적화하고 클라이언트에서의 부담을 줄일 수 있지만, 클라이언트에서 직접적인 상호작용이 필요하다면 적절하게 조합하여 사용하는 것을 권장합니다. 기본 SSR은 비교적 구현이 쉽지만 성능이 낮을 수 있으며, 스트리밍 SSR은 가장 빠른 사용자 경험을 제공하지만 구현이 복잡할 수 있습니다.

React 19에서 서버 컴포넌트 + 스트리밍 SSR 조합으로 작성하고, Next.js를 활용해보는 것을 권장합니다. 프로젝트의 요구 사항에 맞게 적절한 렌더링 방식을 선택할 수 있길 바랍니다.

TI Tech Lab 이유진 연구원

Source

Avatar

theinnovators

Add comment