개발 관련 토막지식

Streaming SSR

dev_in 2026. 4. 2. 13:03

 

Streaming SSR

Streaming SSR은 서버에서 렌더링된 HTML을 한 번에 완성해서 보내는 방식이 아니라, 준비된 부분부터 점진적으로 스트리밍해서 클라이언트에 전달하는 기술입니다. 이를 통해 사용자는 페이지의 중요한 콘텐츠를 더 빠르게 확인할 수 있습니다.

기존 SSR은 서버에서 모든 데이터를 처리한 뒤 완전한 HTML을 전송하는 반면, Streaming SSR은 서버가 데이터를 준비하는 즉시 HTML 조각을 스트림 형태로 보내고, 클라이언트는 이를 실시간으로 렌더링합니다. React 18에서는 renderToPipeableStream API를 통해 구현할 수 있으며, 이 API는 서버에서 HTML을 조각 단위로 스트리밍할 수 있도록 지원합니다. 예를 들어, onShellReady 옵션을 사용해 스트림을 응답으로 바로 전송할 수 있습니다.

renderToPipeableStream(<App />, {
  onShellReady() {
    res.setHeader('Content-Type', 'text/html');
    stream.pipe(res);
  },
});

이 방식의 가장 큰 장점은 초기 로딩 시간을 단축할 수 있다는 점입니다. HTML의 일부라도 준비되는 즉시 클라이언트가 렌더링을 시작하므로 TTFB(Time to First Byte)가 개선됩니다. 특히 데이터가 많거나 복잡한 대규모 애플리케이션에서 효과적이며, 사용자가 중요한 콘텐츠를 먼저 확인할 수 있어 전반적인 사용자 경험도 향상됩니다.

다만, 클라이언트에서 부분적으로 전송된 HTML을 제대로 Hydration할 수 있도록 설계가 필요하며, SEO나 캐싱 정책과의 호환성도 신중히 고려해야 합니다.

이러한 특징과 장점을 통해 Streaming SSR은 기존 SSR의 한계를 극복하며, 더욱 빠르고 효율적인 웹 페이지 렌더링을 가능하게 만듭니다.

 

스트리밍된 데이터와 리액트의 Hydration 과정에서 발생할 수 있는 문제

HTML과 리액트 상태의 불일치 문제는 스트리밍된 HTML이 서버에서 먼저 클라이언트로 전송되고, 리액트가 실행되기 전까지는 그냥 정적인 상태로만 보여지는 데서 시작됩니다. 이후 Hydration 과정에서 이 HTML에 리액트의 상태와 이벤트 핸들러가 결합되는데, 이때 서버와 클라이언트 사이 데이터가 맞지 않으면 문제가 생길 수 있습니다.

예를 들어, 서버에서 렌더링된 데이터가 클라이언트에서 Hydration 시점에 변경되어 있다면 리액트가 경고를 띄우거나, 예상치 못한 UI 동작이 나타날 수 있습니다. 또, 비동기 데이터 처리를 Suspense로 하고 있다면, 데이터가 늦게 로드되면서 UI가 달라질 가능성도 있습니다.

 

불일치 문제를 해결 방법

이런 문제를 막으려면, 서버와 클라이언트에서 동일한 데이터 소스를 사용해야 합니다. 예를 들어, Tanstack Query 같은 라이브러리를 활용하면 데이터를 동기화하기가 훨씬 수월해집니다. 또, Suspense와 fallback을 잘 활용하면, 데이터가 아직 준비되지 않았을 때도 안정적인 화면을 보여줄 수 있습니다. 이렇게 하면 사용자 입장에서 데이터가 로드되기 전에 UI가 흔들리는 문제를 줄일 수 있습니다.