"현재 클라이언트가 받은 웹 페이지는 단순히 웹 화면만 보여주는 HTML일 뿐이고, JS 요소들이 하나도 없는 상태이다. 이는 웹 화면을 보여주고 있지만, 특정 JS 모듈 뿐 아니라 단순 클릭과 같은 이벤트 리스너들이 각 웹 페이지의 DOM 요소에 하나도 적용되어 있지 않은 상태임을 말한다. 그러면 이렇게 페이지만 보여주고 동작조차 하지 못하는 마치 빈 껍데기 같은 웹 페이지가 나중에는 어떻게 정상적으로 동작하게 되는 것일까."

Hydrate

  • Next.js의 주요 동작 방식
  • 페이지가 브라우저에 로드되고 JS 코드가 실행되면서 페이지가 인터렉티브하게 동작하는 상태가 되는 과정
  • Server Side 단에서 렌더링된 정적 페이지와 번들링된 JS파일을 클라이언트에게 보낸 뒤, 클라이언트단에서 HTML 코드와 React인 JS 코드를 서로 매칭시키는 과정
    "Next.js Server에서는 Pre-Rendering된 웹 페이지를 클라이언트에게 보내고 나서, 바로 리액트가 번들링 된 JS 코드들을 클라이언트에게 전송한다."

"네트워크 탭을 보면, 맨 처음 응답받는 요소가 document Type의 파일이고, 이후에 React 코드들이 렌더링 된 JS 파일들이 Chunk 단위로 다운로드되는 것을 확인할 수 있다. 그리고 이 JS 코드들이 이전에 보내진 HTML DOM 요소 위에서 한번 더 렌더링을 하면서, 각자 자기 자리를 찾아가며 매칭이 된다. 이 과정을 Hydrate라고 부른다. 이것은 마치 자바스크립트 코드들이 DOM 요소 위에 물을 채우 듯 필요로 하던 요소들을 채운다 하여 Hydrate(수화)라는 용어를 쓴다고 한다."

"새롭게 페이지를 로딩할 때마다 약간 뒤늦게 스타일이 적용되는 듯한 이 과정이, HTML DOM 요소에 뒤늦게 자바스크립트가 동작하고 Hydration 돼서 나타나는 현상이다."

"어쩌면 두번 렌더링 하는 것은 비효율적으로 보일 수 있다. 그러나 서버 단에서 빠르게 Pre-Rendering하고 유저에게 빠른 웹 페이지로 응답할 수 있다는 것에 더욱 큰 이점을 가져갈 수 있다. 심지어 이 Pre-Rendering 한 Document는 모든 자바스크립트 요소들이 빠진 굉장히 가벼운 상태이므로 클라이언트에게 빠른 로딩이 가능하다."

출처

Hydrate / Dehydrate

"서버가 완성된 HTML을 내려준다. 이때 Dehydrate는 수분을 없앤다는 뜻이다. 다시 말해서 동적인것을 정적으로 만드는 행위를 Dehydrate라고 표현했다. 그리고 나서 JS가 실행되면서 리액트가 정적인 HTML과 store를 동적인 리액트 컴포넌트 트리와 store로 변환하는 과정이 일어나는데, 이걸 (Re)hydrate라고 한다. 마치 수분기 없는 정적인 상태에서 수분 넘치는 동적인 상태로 변화한것이다. 문제는 이렇게 rehydrate가 일어나면서 쓸데없이 화면이 한번더 그려지는 현상이 발생한다는것이다. 왜냐면 리액트는 서버에서 완성된 HTML이 내려와서 이미 화면에 제대로 렌더링이 됬는지 안됬는지 모르고 자신이 할일을 그냥 했을 뿐이다. 그래서 SSR을 하는 경우에는 ReactDom의 render메소드가 아니라 hydrate 메소드를 사용해야 한다고 말했었다."

출처 - React의 Hydration

HTML Streaming과 Selective Hydration

" 하지만 잘못 설계하면 기존의 폭포수 방식의 렌더링에 비해 성능에 상당한 단점이 있을 수도 있다. 그 단점은 First Paint를 개선하더라도 Time To Interactive에는 부정적인 영향을 미칠 수 있다는 것이다. SSR의 페이지는 종종 엄청나게 빨리 로드되고 인터렉션 가능한 것처럼 보이지만 실제로 클라이언트 측 JS가 실행되고 이벤트 핸들러가 첨부 될 때까지 입력에 응답할 수 없을 수 있다. 또한 이 응답할 수 없는 시간은 모바일에서는 몇 초, 심지어 몇 분이 걸릴 수 있다. 그래서 페이지 로드는 되었지만 일정 시간동안 클릭하거나 터치해도 반응이 없는 경우 고객은 빠르게 실망으로 변한다.(이탈률도 굉장히 높아질 것이다.) React v18에서의 주요 변경점 중 하나가 HTML Streaming과 점진적인 Hydration이다. 이 방법을 사용하면 서버 렌더링 애플리케이션의 개별 부분이 전체 응용 프로그램을 한꺼번에 초기화하는 현재의 일반적인 방식보다는 시간이 지남에 따라 부팅되는 효과를 볼 수 있다. 이러한 효과는 페이지의 우선 순위가 낮은 부분의 클라이언트 측 업그레이드를 지연하여 필요한 JavaScript의 양을 줄이는 방법을 통해 수행된다."

출처 - React의 Hydration에 대하여

Pre-rendering

Next.js는 Pre-rendering 기능을 통해 각각의 페이지들의 돔을 미리 구성하기 때문에, 검색엔진에 최적화되어있으며 해당 페이지가 클라이언트사이드에서 실행되었을 때, 스크립트 코드가 읽히며 상호작용이 가능해진다

Static Generation : Pre-rendering 메소드가 빌드가 될 때 HTML을 구성한다. 이후, 각 요청에는 생성됬던 HTML들이 재사용된다.
Server-side Rendering : 요청이 있을때마다 HTML을 구성한다.
선택적 Pre-rendering : Next.js의 중요한 점은 각각의 페이지들이 어떤 Pre-rendering방식을 사용할 것인지 선택할 수 있다는 점이다.

"두개의 Pre-rendering 어떤 상황에 사용하는가?
사용자의 요청이 없어도 페이지를 렌더링 할 수 있습니까?라고 자문했을 때, 네 라면 정적 생성, 아니오 라면 서버측 렌더링을 사용해야한다."

출처 - Next.js Pre-rendering

Streaming SSR with selective hydration

출처 - 동시성을 구현하는 기술 DEVIEW 2021

Rendering Pattern

"올바른 렌더링 패턴이란, 우리의 어플리케이션의 특성에 맞고, UX와 DX를 모두 높여주는 패턴을 말합니다. 어플리케이션에서 고려해야 할 요소는 검색엔진 최적화, Web Performance등이 있습니다. 검색엔진 최적화는 SSR(Server Side Rendering) 해결할 수 있습니다."

출처 - Rendering Patterns


궁금하면 습관적으로 찾아보는데 정성스럽게 작성해주신 지식공유자분들 덕분에 이해력 상승!
velog에도 좋은 자료가 많아서 이 맛에 velog합니다 🥰 (TIL TIL)

profile
필요한 내용을 공부하고 저장합니다.

0개의 댓글