← 목차7 / 7

07

정리

직접 만들며 알게 된 것들

세 가지 방식

2.400s
shell
콘텐츠
renderToString동기 함수. Suspense를 기다릴 수 없다
Todo List
loading...
여기서 멈춘다
TTFB
0.005s
Total
0.005s
목록
없음
한 번에 보내기완성된 HTML을 다 만든 뒤 전송
Todo List
  • Buy groceries
  • Read a book
  • Write a blog post
TTFB
0.003s
Total
2.007s
목록
포함
스트리밍shell을 먼저, 나머지는 나중에
Todo List
  • Buy groceries
  • Read a book
  • Write a blog post
TTFB
0.006s
Total
2.013s
목록
포함

renderToString은 숫자만 보면 가장 좋습니다. TTFB도 Total도 5밀리초입니다. 그런데 목록이 없습니다. 빠른 것이 아니라 기다리지 않은 것입니다.

한 번에 보내는 방식은 목록을 담지만 그동안 화면이 비어 있습니다.

스트리밍은 shell을 먼저 내보내고 나머지를 나중에 채웁니다. 세 방식 중 유일하게 빠른 첫 화면과 완성된 HTML을 동시에 가집니다.

스트리밍이 실제로 하는 일

복잡해 보이지만 세 단계입니다.

  1. 기다릴 필요 없는 부분(shell)을 먼저 보낸다. 나중에 채울 자리만 표시해둔다.
  2. 완성된 조각을 문서 맨 끝에 hidden으로 보낸다.
  3. 작은 스크립트로 그 조각을 제자리에 옮긴다.

HTML은 이미 보낸 부분을 고칠 수 없기 때문에, 뒤에 덧붙이고 JavaScript로 옮기는 우회를 하는 것입니다.

직접 만들며 알게 된 것

TTFB는 스트리밍 판정에 쓸 수 없다

버퍼링 실험에서는 header가 먼저 나가는 바람에 TTFB가 정상으로 보였고, onAllReady에서는 헤더 전송 시점이 첫 바이트로 잡혀 13밀리초가 나왔습니다. 둘 다 콘텐츠는 2초 뒤에 도착했습니다.

믿을 수 있는 것은 응답 원문에 fallback과 교체 스크립트가 있는지, 그리고 화면에 첫 콘텐츠가 언제 뜨는지입니다.

응답이 같아도 경험이 다를 수 있다

버퍼링 실험에서 응답 원문은 한 글자도 다르지 않았습니다. 서버가 만드는 HTML은 같고 언제 내보내느냐만 달랐습니다.

그런데 사용자는 2초간 빈 화면을 봅니다. 차이가 오직 화면에서만 드러난다는 것이 스트리밍의 본질이기도 합니다.

자리와 내용은 분리되어 있다

자리는 선언 순서로 미리 잡고, 내용은 완료 순서로 채웁니다. id로 찾아가므로 도착 순서가 뒤섞여도 화면은 올바릅니다.

이 분리가 없으면 가장 느린 컴포넌트를 모두가 기다려야 합니다.

마무리

프레임워크 제약도 있었고, 지금 당장 필요한 상황도 아니어서 적용하지는 못했습니다. 그래도 직접 만들어보고 나니 스트리밍이 무엇을 해결하려는 기술인지는 분명해졌습니다.

언젠가 실무에서 이 선택지를 마주쳤을 때, 무엇을 얻고 무엇을 감수하는지 알고 결정할 수 있으면 좋겠습니다. 이 글을 읽으신 분들께도 그런 판단의 재료가 되었으면 합니다.