[서버 사이드 렌더링 - 1단계] 빙봉(김윤경) 미션 제출합니다. #23
Merged
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.
안녕하세요 월하🌙🌝 만나서 반갑습니다! 리뷰 잘 부탁드려요~!
👀 리뷰를 통한 생각 나눔
1. SSR 렌더링 시 초기 렌더링 성능이 왜 유리할까?
SSR이 초기 렌더링 성능에서 유리한 이유는 서버에서 클라이언트의 요청을 처리한 후, 완성된 HTML을 미리 생성해 반환하기 때문입니다. 이 HTML은 페이지의 구조뿐만 아니라 텍스트, 이미지, 스타일 등 필요한 모든 요소를 포함한 완성된 문서로, 브라우저는 이를 받아 별도의 자바스크립트 실행 없이도 즉시 DOM 트리를 생성한 후, 바로 렌더 트리를 만들어 화면에 콘텐츠를 렌더링합니다.
반면, CSR에서는 브라우저가 빈 HTML을 받은 뒤 자바스크립트를 다운로드하고 실행해야만 DOM을 구성할 수 있습니다. 이 자바스크립트는 API 호출을 통해 데이터를 가져온 후, DOM을 동적으로 조작하여 페이지 콘텐츠를 구성합니다. 이러한 과정 때문에 데이터 페칭과 렌더링이 분리되고, 자바스크립트 실행이 완료될 때까지는 화면에 아무것도 표시되지 않기 때문에 초기 로딩 속도가 느려질 수 있습니다.
SSR 렌더링 흐름
CSR 렌더링 흐름
2. 서버에서 렌더링한 영화 목록을 어떻게 클라이언트에 데이터를 전달하고 브라우저에서는 어떤 작업을 수행할까?
서버는 React의 renderToString함수를 사용하여 React 트리를 HTML 문자열로 변환합니다. 이 때,
App
컴포넌트는 서버가 가져온movies
데이터를 속성으로 받아, 해당 데이터를 기반으로 서버에서 미리 완성된 HTML을 생성합니다.서버는
index.html
파일을 읽어와renderToString
으로 생성된 HTML을div#root
에 삽입합니다. 이 과정에서 서버는 클라이언트가 사용할 영화 데이터를<script>
태그를 통해window.__INITIAL_DATA__
에 저장하여 직렬화(serialize) 합니다.클라이언트(브라우저)는 서버에서 전송된 HTML을 수신하고, 이를 화면에 즉시 렌더링합니다. 이 때 화면에 표시된 내용은 정적인 HTML로, 사용자가 상호작용할 수 없는 상태입니다. 즉, 화면에 영화 목록이 표시되더라도, 버튼 클릭, 페이지 전환 등의 동작은 아직 불가능합니다.
브라우저가 HTML을 렌더링한 이후, React 자바스크립트 파일이 로드됩니다. 이 때 하이드레이션(hydration) 과정이 시작되는데, 하이드레이션은 서버에서 미리 렌더링된 HTML을 기반으로, React 컴포넌트를 상호작용이 가능한 동적인 상태로 전환하는 과정입니다.
하이드레이션은 React에서 제공하는 hydrateRoot 함수를 사용하여 수행됩니다.
hydrateRoot
는 브라우저가 이미 화면에 렌더링된 정적인 HTML을 가져와, 해당 구조와 동일한 React 컴포넌트를 로드하고 이를 활성화하는 역할을 합니다.이 과정에서 React는 서버에서 렌더링된 DOM과 클라이언트 측에서 로드된 React 트리의 구조를 비교하여 DOM을 다시 그리는 대신 이벤트 핸들러와 같은 동적 동작을 활성화합니다. 이를 통해 버튼 클릭과 같은 사용자 상호작용이 가능해집니다.
클라이언트 측에서는 서버에서 전달된 초기 데이터를
window.__INITIAL_DATA__
로부터 받아와, React 컴포넌트에 이를 전달합니다. 이로 인해 클라이언트는 별도로 데이터를 다시 요청할 필요 없이, 서버에서 전달받은 데이터를 그대로 사용하여 페이지를 활성화할 수 있습니다.이 데이터는 React 앱의 초기 상태로 설정되며, 서버에서 받은 HTML과 데이터가 정확히 일치하므로 추가적인 데이터 요청 없이 빠르게 상호작용 가능한 상태로 전환됩니다.
3. 전역 객체 초기화 작업은 왜 진행해야 할까?
전역 객체 초기화 작업은 서버와 클라이언트 간의 일치성을 유지하고, 상호작용을 원활하게 하기 위해 필요한 것 같습니다.
미션을 구현하면서 아래와 같은 오류를 만났습니다.
해당 에러가 발생했던 이유는 서버에서 렌더링된 HTML과 클라이언트 측에서 React가 다시 렌더링하는 결과가 서로 다르기 때문입니다.
서버 측에서 데이터를 받아 렌더링할 때는
movies
데이터가 포함되어 있지만, 클라이언트 측에서 React가 처음 로드되었을 때는movies
에 대한 초기 데이터가 없습니다. 그래서 클라이언트와 서버에서 다른 렌더링 결과를 낳게 되고, 위와 같은 에러를 발생합니다.