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과 리액트 상태의 불일치 문제는 스트리밍된 HTML이 서버에서 먼저 클라이언트로 전송되고, 리액트가 실행되기 전까지는 그냥 정적인 상태로만 보여지는 데서 시작됩니다. 이후 Hydration 과정에서 이 HTML에 리액트의 상태와 이벤트 핸들러가 결합되는데, 이때 서버와 클라이언트 사이 데이터가 맞지 않으면 문제가 생길 수 있습니다.
예를 들어, 서버에서 렌더링된 데이터가 클라이언트에서 Hydration 시점에 변경되어 있다면 리액트가 경고를 띄우거나, 예상치 못한 UI 동작이 나타날 수 있습니다. 또, 비동기 데이터 처리를 Suspense로 하고 있다면, 데이터가 늦게 로드되면서 UI가 달라질 가능성도 있습니다.
그럼 이러한 불일치 문제를 해결하려면 어떻게 해야하나요? 🧐
이런 문제를 막으려면, 서버와 클라이언트에서 동일한 데이터 소스를 사용해야 합니다. 예를 들어, Tanstack Query 같은 라이브러리를 활용하면 데이터를 동기화하기가 훨씬 수월해집니다. 또, Suspense와 fallback을 잘 활용하면, 데이터가 아직 준비되지 않았을 때도 안정적인 화면을 보여줄 수 있습니다. 이렇게 하면 사용자 입장에서 데이터가 로드되기 전에 UI가 흔들리는 문제를 줄일 수 있습니다.