스트리밍의 마법

172025년 09월 01일4

선택적 하이드레이션은 사용자가 페이지와 상호작용할 수 있는 시점을 극적으로 앞당겼다. 하지만 여전히 해결되지 않은 문제가 있었다. 만약 페이지의 특정 부분이 데이터를 가져오는 데 아주 오랜 시간이 걸린다면 어떻게 될까?

예를 들어, 페이스북의 뉴스피드 페이지를 생각해보자. 페이지의 헤더나 좌측 내비게이션 바는 빠르게 렌더링할 수 있지만, 메인 콘텐츠 영역인 뉴스피드 자체는 친구들의 소식, 광고, 추천 그룹 등 수많은 데이터를 조합해야 해서 시간이 오래 걸릴 수밖에 없었다.

기존 방식대로라면, 서버는 가장 느린 뉴스피드 데이터까지 모두 준비될 때까지 기다렸다가, 전체 페이지의 HTML을 한꺼번에 보내야 했다. 사용자는 그 시간 동안 또다시 하얀 화면과 마주해야 했다.

“우리는 이미 답을 가지고 있어.”

회의 중, 앤드류 클라크가 말했다. 그는 React 18에서 이미 도입되었지만, 서버 컴포넌트의 등장으로 그 잠재력이 완전히 개화할 준비를 마친 기술을 언급했다. 바로 Suspense였다.

Suspense는 ‘아직 준비되지 않았음’을 React에게 알려주는 약속입니다. 우리는 이 약속을 서버 렌더링 과정에 적용할 수 있습니다.”

그의 제안에 따라 팀은 새로운 실험에 착수했다. 시간이 오래 걸리는 NewsFeed 컴포넌트를 Suspense로 감싸고, 데이터가 준비되는 동안 보여줄 fallback UI로 스켈레톤 로딩 화면을 지정했다.

// Page.server.js 
import { Header, Navigation } from './Layout';
import { NewsFeed, NewsFeedSkeleton } from './Feed';
import { Suspense } from 'react';

function Page() {
  return (
    <div>
      <Header />
      <Navigation />
      <main>
        <Suspense fallback={<NewsFeedSkeleton />}>
          <NewsFeed />
        </Suspense>
      </main>
    </div>
  );
}

그리고 서버의 렌더링 로직을 수정했다. 이제 서버는 더 이상 모든 데이터가 준비될 때까지 기다리지 않았다.

  1. 서버는 렌더링을 시작한다. HeaderNavigation은 즉시 렌더링된다.
  2. Suspense 경계를 만난다. 안의 NewsFeed가 데이터를 가져오는 중임을 확인한다.
  3. 서버는 기다리지 않고, NewsFeed 자리에 fallback으로 지정된 <NewsFeedSkeleton />을 채워 넣은 채로, 먼저 완성된 부분의 HTML을 클라이언트로 보내기 시작한다.
  4. 클라이언트는 이 초기 HTML을 받아 즉시 화면에 그린다. 사용자는 헤더와 내비게이션, 그리고 뉴스피드 영역의 스켈레톤 UI를 즉시 볼 수 있다.
  5. 그 시간 동안, 서버는 백그라운드에서 계속 NewsFeed 데이터를 가져온다.
  6. 마침내 데이터가 준비되면, 서버는 NewsFeed 컴포넌트를 렌더링한 HTML 조각을 추가적인 데이터와 함께 클라이언트로 보낸다.
  7. 클라이언트는 이 스트림을 받아, 기존의 스켈레톤 UI를 실제 뉴스피드 콘텐츠로 매끄럽게 교체한다.

이것이 바로 ‘스트리밍(Streaming)’의 마법이었다.

서버는 완성되는 UI 조각들을 순차적으로, 마치 물이 흐르듯 클라이언트로 흘려보냈다. 클라이언트는 더 이상 모든 것이 준비될 때까지 목마르게 기다릴 필요가 없었다. 먼저 도착한 물로 갈증을 해소하고, 뒤따라오는 풍성한 과일을 즐기면 그만이었다.

Suspense와 서버 컴포넌트의 조합은 완벽했다. 서버 컴포넌트는 각 컴포넌트가 독립적으로 데이터를 가져올 수 있게 해주었고, Suspense는 그 데이터 로딩 과정을 사용자 경험의 단절 없이 우아하게 처리해 주었다.

이 스트리밍 렌더링은 네트워크 폭포수 문제를 해결하는 것을 넘어, 사용자 인지 성능(Perceived Performance)을 극적으로 향상시켰다. 실제 전체 로딩 시간은 같더라도, 사용자는 무언가 계속 화면에 나타나고 있다는 느낌을 받으며 훨씬 쾌적하게 서비스를 이용할 수 있었다.

React 19의 거대한 그림이 점점 더 명확해지고 있었다. 서버 컴포넌트는 구조적인 뼈대였고, 선택적 하이드레이션과 스트리밍은 그 뼈대 위를 흐르는 혈액과도 같았다. React는 이제 정적인 문서를 넘어, 살아 숨 쉬는 유기적인 경험을 만들어낼 준비를 하고 있었다.