[React] CSR, SSR, hydrate

Pakxe·2023년 7월 1일

next.js

목록 보기
2/2
post-thumbnail

CSR

빈 html과 모든 로직이 담겨있는 js파일을 받는다. 클라이언트는 이렇게 받은 html에 js로 DOM을 동적으로 생성해 화면을 그려낸다. 이런 과정을 클라이언트 쪽에서 진행하기 때문에 CSR이라는 이름이 붙게 됐다.

이 방식의 장점은 원하는 내용만 업데이트할 수 있어 헤더, 푸터와 같은 고정되어있는 컴포넌트는 깜빡이지 않고 컨텐츠만 업데이트 할 수 있다.

하지만 초기 로딩시 모든 로직이 담긴 js를 받아오기 때문에 느리며, 비어있는 html파일을 받기 때문에 SEO에 약하다.

SSR(pre-rendering)

서버에서 완성된 html을 로드(불러오기)한다.
클라이언트에서 요청할 때마다 html을 완성해 넘겨주기 때문에 페이지가 여러개다(MPA)
csr은 모든 로직이 담겨있는 js파일을 다운로드하지만, SSR은 요청이 들어온 페이지에 필요한 것만 다운로드하기 때문에 초기 로드가 빠르다.
또한 각 페이지에 대한 정보를 습득하기 쉽기 때문에 SEO가 수월하다.
그리고 ^쿠키 관리, 주요 API, 데이터 검증 등과 같은 작업을 서버에서 처리하기 때문에, 중요한 데이터를 클라이언트에 노출할 필요가 없어 안전하다^
또한 html을 보내기 때문에 ^클라이언트 환경이 js를 사용하지 못하거나 오래된 브라우저를 사용해도 웹페이지를 제공할 수 있다.^

하지만 새로운 html파일을 받아올 때 화면 깜빡임 현상이 존재한다. 그리고 헤더, 푸터와 같은 내용을 중복해서 받아온다. (비효율) 따라서 페이지간 이동에 시간이 많이 필요하다.
그리고 완성된 html을 받고 나서 js를 받아오기 때문에 화면은 보여져도 조작을 못하는 경우가 존재하기도 한다. (이런 경우 예로, 버튼을 클릭했다면 클릭했다는 조작을 기억해두었다가 js까지 컴파일되면 기억했던 동작을 수행하는 방식으로 해결한다.)

CSR은 예를들어 버튼을 클릭하면 보이는 모달의 경우 클릭한 후에 react가 동적으로 생성한다. 하지만 next.js는 기본적으로 특정 페이지 내의 모든 리액트 컴포넌트를 서버에서 렌더링하거나 빌드 시점에 미리 렌더링한다. 따라서 window, document같은 브라우저 전용 api, canvas같은 html요소는 클라이언트에서 렌더링하도록 지정하는 방식으로 보통 처리한다.

이때 next.js가 useEffect를 하이드레이션 이후 브라우저에서 실행하도록 해야한다. 이렇게하면 특정 작업을 반드시 클라이언트에서 실행하도록 강제할 수 있다. 또는 useState + useEffect + (상태 변수 && ) 형태로 특정 컴포넌트를 정확히 클라이언트에서만 렌더링하도록 지정할 수도 있다.

hydrate

SSR에서 사용되는 개념이다.
SSR은 pre-rendering으로 완성된 html을 클라이언트에게 전달한다.
이렇게 서버에서 렌더링된 정적 페이지를 클라이언트에게 전달하고, react는 번들링된 js코드를 클라이언트에게 전달한다. 그럼 클라이언트는 전달받은 html, js를 매칭하는 hydrate를 수행하게 된다.

이때 hydrate는 이전에 보내진 html 각각의 DOM 객체에 필요한 js 코드를 추가해서 클라이언트가 동적으로 렌더링할 수 있는 것이다. 서버에서 렌더링한 DOM과 클라이언트가 렌더링한 DOM이 섞여 SPA처럼 보인다는 점에서 hydrate(물과 물에 녹여진 물질이 어우려져 하나의 문자처럼 보이는 현상)이라는 용어를 사용한 것!

hydrate후에 버튼 클릭과 같은 조작이 가능해진다.

SSR 덕분에 사용자는 ui를 먼저 볼 수 있고, hydrate덕분에 js코드가 매칭되어 추후 사용자 조작이 가능해진 것이다.

추가 개념: TTV, TTI

  • TTV(Time To View): 사용자가 브라우저의 내용을 볼 수 있는 시점
  • TTI(Time To Interact): 사용자가 브라우저와 상호작용할 수 있는 시점

우리는 Next.js를 이용해 SSR로 먼저 TTV를 가능하게 하고, hydrate를 통해 TTI를 가능하게 한 것이다. 하지만 CSR의 경우는 html, js 둘의 로딩이 다 끝나야 ui가 보이므로 TTV와 TTI가 같은 시점이 된다.

참고 자료

https://velog.io/@leehyunho2001/Hydrate
이 블로그는 후에 선택적 하이드레이션에 대한 설명도 있기 때문에 읽어보자.

0개의 댓글