SSR을 사용하면 JavaScript 번들이 로드되고 실행되기 전에 사용자가 페이지의 콘텐츠를 볼 수 있음
목적 : 앱의 사용자가 콘텐츠를 더 빨리 보고 훨씬 더 빠르게 상호 작용을 시작
유튜브,네이버 등등 타 사이트의 경우, 느린 네트워크 환경에서도 뷰포인트의 일부분을 먼저 보여줌으로써 사용자에게 이 페이지가 멈추지 않음을 느끼게 해줌
일부분이 아직 로딩 스페너가 돌아가고 있고, 이미지,썸네일의 경우 스켈레톤 처리 되어 있어도, 헤더나 메뉴의 경우 클릭이 가능함
이렇게 사용자가 페이지가 멈추지 않았음을 느끼게 하는게 UX측면에서 굉장히 중요하다는 것을 깨달음
상호작용 가능한 상태를 만들려면 모든것을 수화(Hydrate)해야함
즉, 수화가 시작된 후에는(컴포넌트 함수를 호출한 후에는) 전체 트리에 대해 이 작업이 완료될 때까지 React가 멈추지 않음. 그래서 모든 컴포넌트가 수화될때까지 기다려야함
댓글기능에는 비용이 많이드는 렌더링 로직이 있다고 가정해보자.
내 컴퓨터에서는 빠르게 작동할 수 있지만, 저사양 기기에서는 그 로직을 실행하는데에 비용이 많이 들고, 화면이 멈출 수 있음. 물론 이런 기능은 Server Components를 사용하는 게 이상적임. 하지만 일부 로직은 이벤트 핸들러를 사용하는게 불가피해서 어쩔 수 없음. 어쨋든, 수화가 시작되면 전체 트리가 수화될때까지 사용자는 네비게이션바, 헤더, 사이드바 등등과 상호작용할 수가 없음. 사용자는 사이드바나 네비게이션바와 상호작용하여(홈을 누른다던지, 다른 마이페이지로 이동한다던지) 이 페이지를 완전히 벗어나고 싶지만, 계속해서 수화가 일어나고 있어서 현재 페이지에 머물 수 밖에 없음
결국 둘 중 선택해야함
댓글을 서버 출력에서 제외하여 사용자가 JS가 로드될때까지 댓글을 못보게 하거나,
서버출력에 포함해서 댓글이 로드되고 전체 트리를 렌더링될때까지 다른 HTML과의 상호작용을 지연시키거나
이런 것들은 waterfall한 구조때문임
데이터 패칭(서버)->HTML로 렌더링(서버)->코드 로드(클라이언트)-> 수화(클라이언트)
앞 단계가 완료되기전까지 다음 단계를 실행할 수 없음
결국 해결책은 화면의 일부에 대해 각 단계를 수행할 수 있도록 작업을 분리하는 것임
React18부터 이게 가능한 <Suspense>가 정식 적용됨
댓글을 서스펜스로 감싼다
<Suspense fallback={<Spinner />}>
<Comments />
</Suspense>
<Comments>
를 <Suspense>
로 래핑함으로써, React에게 댓글을 스트리밍하기 위해 기다릴 필요가 없다고 알림. 대신, React는 댓글 대신 플레이스홀더(스피너)를 보냄
초기 HTML에서 Comments는 빠지고 그자리를 spinner가 대체함
댓글에 대한 데이터가 준비되면 React는 추가 HTML을 동일한 스크림으로 보냄
그러면 React자체가 클라이언트에 로드되기 전에 댓글에 대한 HTML이 팝업됨
이제 문제 하나가 해결됨
화면의 일부가 초기 HTML을 지연시킬 경우 모든 HTML을 지연시키거나 HTML에서 제외할지 선택할 필요가 없게됨
초기 HTML을 더 일찍 보낼 수 있지만, 댓글의 JavaScript코드가 로드될 떄까지 클라이언트에서 앱을 수화할 수 없음. 코드 크기가 크면 시간 많이걸림.
그래서 이런 대규모 번들을 피하기 위해 '코드 분할'을 사용해야함.
React.lazy
를 사용하여 기본 번들에서 Comments코드를 분리
이렇게 React 18 <Suspense>
에서는 댓글 위젯이 로드되기 전에 앱을 하이드레이션할 수 있음
🫠
출처 : https://github.com/reactwg/react-18/discussions/37#top