[2팀 이정민] Chapter 4-1 성능최적화: SSR, SSG, Infra#31
Open
LEE-jm96 wants to merge 7 commits intohanghae-plus:mainfrom
Open
[2팀 이정민] Chapter 4-1 성능최적화: SSR, SSG, Infra#31LEE-jm96 wants to merge 7 commits intohanghae-plus:mainfrom
LEE-jm96 wants to merge 7 commits intohanghae-plus:mainfrom
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
과제 체크포인트
배포 링크
vanilla: https://lee-jm96.github.io/front_7th_chapter4-1/vanilla/
기본과제 (Vanilla SSR & SSG)
Express SSR 서버
<!--app-html-->,<!--app-head-->)서버 사이드 렌더링
클라이언트 Hydration
window.__INITIAL_DATA__스크립트 주입Static Site Generation
심화과제 (React SSR & SSG)
React SSR
renderToString서버 렌더링React Hydration
Static Site Generation
아하! 모먼트 (A-ha! Moment)
처음에는 SSR과 CSR의 차이를 그저 렌더링이 서버에서 되느냐, 브라우저에서 되느냐 정도로만 이해하고 있었습니다. 그래서 서버에서 HTML을 내려주면 클라이언트는 그냥 그 위에서 다시 시작하는 것이라고 막연히 생각했습니다. 그런데 구조를 하나씩 따라가다 보니 문제는 렌더링 위치가 아니라 상태의 출발점이라는 걸 알게 되었습니다. 서버에서는 이미 페이지에 필요한 데이터를 모두 프리페칭하고 있는데, 클라이언트가 시작할 때 그 사실을 전혀 모르고 다시 “빈 상태”에서 API 요청을 반복하고 있었습니다. 이때 window.__INITIAL_DATA__의 역할이 보이기 시작했습니다. 서버에서 만든 데이터를 HTML에 그대로 주입해 두고, 클라이언트는 hydration 과정에서 그 값을 읽어 스토어 상태를 복원합니다.
이 과정을 거치면서 클라이언트는 서버와 완전히 같은 상태에서 출발하게 되고, 불필요한 재요청도, 상태 불일치도 사라지는 것을 알게 됐습니다.
이제 보니 SSR → CSR 전환은 새로 렌더링을 시작하는 과정이 아니라 서버에서 만들어진 상태를 이어받는 과정이었습니다.
결국 SSR의 핵심은 서버에서 UI를 미리 그리는 것이 아니라 서버에서 준비한 상태를 클라이언트가 그대로 이어서 사용하는 것이라는 걸 이번 구조를 통해 체감하게 되었습니다.
자유롭게 회고하기
처음에는 SSR과 CSR의 차이를 정말 단순하게만 생각하고 있었습니다.
<div id="root"></div>안에 처음부터 내용이 있느냐, 없느냐 그 정도의 차이라고만 받아들이고 있었던 것 같습니다.CSR은 비어 있는 root에 자바스크립트가 실행된 뒤에 화면이 그려지고, SSR은 서버에서 이미 그린 HTML이 들어 있으니 “아, 그래서 SSR이 빠르구나” 정도로 이해하고 있었습니다. 그런데 구조를 따라가면서 보니 이 차이는 원인이 아니라 결과에 가깝다는 걸 알게 되었습니다.
SSR에서 #root 안에 내용이 들어 있는 이유는 단순히 서버에서 미리 렌더링했기 때문이 아니라, 서버가 이미 데이터를 알고 있는 상태로 렌더링을 했고, 그 상태를 클라이언트가 그대로 이어받기 때문이었습니다.
반대로 CSR은 HTML도 비어 있고, 상태도 비어 있는 상태에서 클라이언트가 모든 걸 처음부터 다시 시작합니다.
이 지점에서 깨달은 건 SSR과 CSR의 차이가 “HTML에 뭐가 들어 있느냐”의 문제가 아니라, 클라이언트의 시작 상태가 다르다는 점이었습니다.
SSR은 서버에서 만들어진 화면과 상태를 클라이언트가 끊김 없이 이어받는 구조이고, CSR은 처음부터 끝까지 클라이언트가 혼자 만들어가는 구조였습니다. 그래서 결국
<div id="root"></div>안에 첫 렌더링 때 내용이 있느냐 없느냐는 SSR과 CSR을 구분해주는 가장 눈에 띄는 차이일 뿐, 그 뒤에는 “상태를 이어받느냐, 다시 시작하느냐” 라는 훨씬 본질적인 차이가 숨어 있다는 걸 이번에야 제대로 이해하게 되었습니다.리뷰 받고 싶은 내용
실무 환경에서도 서버 사이드 렌더링 과정에서 서버가 미리 프리페칭한 데이터를 window.__INITIAL_DATA__와 같은 전역 객체에 주입한 뒤,
클라이언트가 hydration 단계에서 해당 데이터를 읽어 초기 스토어 상태를 복원하는 방식이 일반적으로 사용되는지 궁금합니다.
또한 이러한 전역 데이터 주입 방식이 SSR과 CSR 간 상태 불일치를 방지하기 위한 표준적인 패턴인지, 아니면 Next.js나 특정 프레임워크 내부 구현에 가까운 방식인지도 함께 알고 싶습니다!