뭉균의 개발일지

[Next.js] SSR 과정과 hydration에 대하여 본문

Next.js

[Next.js] SSR 과정과 hydration에 대하여

박뭉균 2024. 9. 27. 20:37

🚪 들어가며

 

지난 글에서 React와 비교했을 때, Next.js를 사용해야하는 이유에 대해 포스팅했습니다.(참고: https://mungyun.tistory.com/10)

 

[Next.js] 리액트만 사용할 때와 비교해 Next.js를 사용하는 이유

🚪 들어가며 React는 웹 애플리케이션 개발에서 널리 사용되는 라이브러리로, 컴포넌트 기반 아키텍처 덕분에 재사용성과 유지보수성이 높은 코드를 작성할 수 있습니다. 그러나 단일 페이지

mungyun.tistory.com

이번 포스팅에서는 React의 CSR, Next.js의 SSR의 과정을 자세히 살펴보고자 합니다. 

 

 

📌 React의 CSR 동작 과정

 

리엑트의 CSR 과정

 

 

 

1. 접속 요청: 사용자가 웹사이트를 방문하면, 브라우저는 서버에 HTML 파일을 요청합니다. 

 

2. 빈 HTML 페이지: 서버에서 전송된 HTML 파일은 보통 빈 <div id="root"></div> 같은 단순한 구조만 포함하고 있으며, 페이지를 채우기 위해 필요한 JavaScript 파일도 함께 전송됩니다.

 

3. JavaScript 번들링 및 실행: 브라우저는 서버로부터 전달받은 JavaScript 파일을 다운로드한 후 실행합니다. 이 JavaScript 파일은 React 앱을 초기화하고, React DOM 라이브러리를 사용하여 HTML을 동적으로 생성하고 렌더링합니다.

 

4. 컨텐츠 렌더링: React는 render 메서드를 통해 컴포넌트 트리를 생성하고, document.getElementById('root') 같은 DOM 요소에 해당 트리를 주입합니다. 이 과정에서 React는 UI를 동적으로 그리며, 브라우저에서 최종 UI가 표시됩니다.

 

5. 동적 상호작용: JavaScript가 완료된 후 사용자와의 상호작용(버튼 클릭, 폼 제출 등)이 동적으로 처리됩니다. React는 상태 관리와 이벤트 처리를 통해 이러한 상호작용을 효율적으로 처리합니다.

 

여기서 FCP라는 개념이 등장하는 데 자세히 알아보겠습니다.

FCP(First Contentful Paint)는 웹 성능 지표 중 하나로, 사용자가 웹 페이지를 요청한 후 처음으로 콘텐츠가 화면에 표시되는 시점을 측정합니다. 여기서 "콘텐츠"는 텍스트, 이미지, SVG 등 화면에 그려지는 의미 있는 요소들을 의미합니다.

 

React가 클라이언트 측에서 작동하는 CSR(Client-Side Rendering) 방식이기 때문인데, 이 방식은 HTML이 서버에서 완전히 렌더링되지 않고, 브라우저가 JavaScript를 다운로드하고 실행한 후에 화면에 콘텐츠를 표시하기 때문에 초기 로드 시간이 길어질 가능성이 있어 FCP를 최적화하는 데 한계가 있습니다. 이 점을 개선하기 위해 SSR(Server-Side Rendering)의 개념이 등장합니다.

 

 

📌 Next.js의 SSR 동작 과정

 

Next.js의 SSR 과정

 

 

 

1. 접속 요청: 사용자가 브라우저에서 특정 URL에 접속하면, 브라우저는 서버에 해당 URL에 대한 요청을 보냅니다. 이때 서버는 해당 페이지의 요청을 받아 SSR을 수행하게 됩니다.

 

2. 서버에서 페이지 렌더링:Next.js는 요청된 페이지에 맞는 React 컴포넌트를 서버에서 실행하여 HTML을 미리 생성합니다. 이 과정에서 필요한 데이터가 있으면 서버에서 API 호출이나 데이터베이스 쿼리 등을 통해 데이터를 받아와, 그 데이터를 이용해 컴포넌트와 함께 최종 HTML을 완성합니다.

 

3. HTML 전송:서버에서 완성된 HTML은 클라이언트로 전송됩니다. 이때 전달되는 HTML은 이미 렌더링된 상태이므로, 사용자는 즉시 콘텐츠를 볼 수 있습니다. 브라우저는 이 HTML을 렌더링하여 페이지를 화면에 보여줍니다.

 

4. Hydration: HTML이 클라이언트에서 렌더링된 후, Next.js는 JavaScript 번들을 다운로드하고 실행하여 페이지를 Hydration합니다. 이는 HTML과 React 컴포넌트를 연결하는 과정으로, 이를 통해 클라이언트에서 동적인 상호작용이 가능해집니다. 즉, 서버에서 렌더링된 정적인 HTML에 React의 기능을 주입하여 이후에는 클라이언트 측에서 React의 상태 관리 및 이벤트 처리가 동작하게 됩니다. Hydration에 대해서는 아래에서 자세히 알아보겠습니다.

 

5. 사용자 상호작용: Hydration이 완료된 후, React는 브라우저에서 완전히 동작하게 되며, 사용자는 React 컴포넌트를 통해 동적인 상호작용을 할 수 있습니다. 이 과정은 CSR에서의 상호작용과 동일하게 동작합니다.

 

이 과정에서 TTI라는 새로운 개념이 등장합니다. 

TTI(Time to Interactive)는 웹 성능 지표 중 하나로, 사용자가 페이지를 방문한 후 완전히 상호작용할 수 있게 되는 시점
을 측정하는 지표입니다. 즉, 페이지가 처음 표시되고 나서 사용자가 버튼을 클릭하거나 스크롤을 하는 등의 상호작용을
즉시 수행할 수 있는 시점이 언제인지를 나타냅니다.

 

FCP와 TTI는 각각 페이지가 사용자에게 처음 보이는 시점사용자가 페이지와 상호작용할 수 있는 시점을 나타냅니다.  프론트엔드 개발자는 이 두 지표를 최적화하여 사용자에게 빠르고 원활한 경험을 제공할 필요가 있습니다.

 

 

📌 Hydration이란? 

 

Hydration의 사전적 정의

출처: unsplash

 

Hydration은 일반적으로 "수화(수분 공급)"라는 의미로 사용됩니다. 물리학이나 생리학에서 이 용어는 물이 어떤 물질에 흡수되거나 결합하는 과정을 설명하는 데 쓰입니다. 즉, 수분을 보충하거나 물에 의해 활성화되는 것을 의미합니다.

 

 

SSR에서의 Hydration 정의

SSR의 경우, 서버에서 이미 생성된 HTML을 클라이언트에게 보내기 때문에 사용자에게는 정적 콘텐츠가 빠르게 표시됩니다. 그러나, 이 HTML은 React와 같은 라이브러리에서 동작하는 동적인 인터랙션이 필요하기 때문에, 클라이언트 측에서 추가적으로 JavaScript 번들이 다운로드 및 실행되어 기존 HTML과 React 컴포넌트를 연결하는 과정을 거칩니다. 이 연결 과정을 Hydration이라고 합니다. Hydration 서버에서 미리 렌더링된 HTML에 클라이언트 측에서 JavaScript 기능을 활성화하여 동적 상호작용을 가능하게 하는 과정을 의미합니다. 정적 HTML에 JavaScript를 주입하여 살아 움직이게 하는 과정이 마치 메마른 땅에 물을 주어 생명을 불어넣는 것처럼 동작합니다.

 

 

💡 결론

 

이번 포스팅에서는 React의 CSR(Client-Side Rendering)과 Next.js의 SSR(Server-Side Rendering)의 동작 과정에 대해 알아봤습니다. 

React의 CSR은 SPA(Single Page Application)에 적합하지만, 초기 로드 시간이 길어지는 문제가 있을 수 있습니다. 반면, Next.js의 SSR은 초기 콘텐츠를 빠르게 표시하여 FCP를 개선하고, 클라이언트에서 상호작용 가능 시점까지 시간을 단축하여 TTI를 최적화하는 데 유리합니다. 따라서, 빠른 초기 로드와 상호작용성을 고려할 때, Next.js는 서버에서 미리 렌더링된 HTML을 제공하고 동적 기능을 추가하는 과정에서 매우 효율적인 선택이 될 수 있습니다.

 

 

📚 참고 자료

1. 공식 문서: https://nextjs.org/docs/app/building-your-application/caching#3-react-hydration-and-reconciliation-on-the-client

 

Building Your Application: Caching | Next.js

An overview of caching mechanisms in Next.js.

nextjs.org

 

2. 한 입 크기로 잘라먹는 Next.js(15+)