Next.js에서 SSR을 실행하는 과정
Next.js를 말할 때 서버 사이드 렌더링(SSR)을 빼놓고 이야기할 수는 없다.
순수 리액트에서는 민감한 정보를 다룰 때도 클라이언트에서 노출될 수 있는 클라이언트 사이드에서 모든 로직을 만들게 되는데, Next.js에서는 SSR이 적용된 컴포넌트에서 클라이언트에 노출될 염려없이 데이터를 다룰 수 있다.
또한, Next.js에서는 페이지의 렌더링 자체가 서버 사이드에서 이루어진다. 그래서 사용자가 웹페이지에 접속하면 서버에서 미리 렌더링되어 있던 화면이 사용자의 요청에 의해 표출되고, 사용자는 빠른 속도로 콘텐츠를 볼 수 있다.
데이터 또한 서버에서 미리 렌더링되고, 사용자의 요청이 들어올 때 전달하는 방식을 취한다. 그 과정에서 이미지같은 경우 Lazy loading 기능을 통해 페이지에 여러 개의 이미지들이 있을 때 사용자가 스크롤을 내리며 아래쪽에 있는 이미지를 보게될 즈음에 전달하여 화면에 표출할 수도 있다.
이렇게 서버 사이드 렌더링은 Next.js 프로젝트에서 중요한 역할을 한다.
SSR은 Next.js의 pages router 방식과 app router 방식에서 사용방식이 조금 다르다.
먼저 Pages router 방식에서 컴포넌트는 기본적으로 클라이언트 사이드 렌더링(CSR)이 적용된다.
따라서 별다른 작업없이 리액트 훅을 사용하거나 이벤트 핸들러를 만들어 활용할 수 있다. 만약 특정 작업을 서버 사이드에서 해야한다면 getServerSideProps라는 이름으로 함수를 만들어서 내부에서 해당 작업을 진행해야 한다.
반면, App router 방식에서 컴포넌트는 기본적으로 서버 사이드 렌더링이 적용되어 있다.
여기서 리액트 훅이나 이벤트 핸들러 등을 활용하지 않는다면 해당 페이지를 서버에서 미리 렌더링하여 사용자에게 빨리 보여줄 수 있다.
그리고 컴포넌트 상단에 "use client"를 입력하여 해당 컴포넌트를 클라이언트 사이드에서 렌더링되도록 할 수 있으며, 사용자와 상호작용을 할 수 있는 여러 기능들을 넣을 수 있다.
만약 부모 컴포넌트에 CSR이 적용되어 있다면 자식 컴포넌트는 자동으로 CSR이 적용된다. 또한, SSR 컴포넌트의 자식 컴포넌트에서도 CSR을 적용하여 사용할 수 있다.
그런데 여기서 중요한 점이 있다. App router 방식에서 hydrate와 관련되어 있는건데, 다음과 같다.
- 서버 컴포넌트: 서버에서 렌더링이 진행되고 클라이언트에서 hydration 되지 않는다.
- 클라이언트 컴포넌트: 서버에서 렌더링이 진행되고 클라이언트에서 hydration 된다.
이러한 특징 때문에 use client 지시어 대신 use hydrate라고 해야하는 것 아닌가에 대한 이야기가 많이 보인다.
Next.js의 Hydration
리액트에는 Hydration이라는 특징이 있다.
기본적으로 웹페이지가 렌더링될 때 가장 먼저 전달되는 HTML 파일에는 사용자와 어떠한 상호작용을 할 수 없는 비활성화상태로 놓여 있게 된다.
그런데 여기에 렌더링이 진행되면서 자바스크립트가 로딩되면 활성화 상태가 된다. 이렇게 HTML 파일을 상호작용할 수 있도록 활성화시키는 것을 Hydration이라고 한다.
Next.js에서의 Hydration은 위에서 적은 SSR과 작동방식에서 연관이 되어 있다.
위 그림은 Next.js에서 hydration이 일어나기까지의 과정을 그려본 것이다.
서버 사이드에서 유저의 페이지 요청에 따라 서버에서 HTML을 생성 후 클라이언트로 보낸다.
그런 후에 DOM이 생성되고 초기 UI가 표출되며, CSSOM 트리도 생성 후 렌더트리를 거쳐 클라이언트측에서 자바스크립트를 불러오게 된다.
만약 이 자바스크립트가 로드되지 않으면 표출된 HTML 파일은 아무런 상호작용이 안되는 상태이다.
자바스크립트가 로드되면 HTML을 활성화하는 Hydration이 일어나게 되고 사용자와의 상호작용이 가능한 상태가 된다.
이렇게 활성화하면서 리액트는 서버에서 생성된 HTML과 클라이언트에서 렌더링된 HTML이 일치하는지 확인하게 되고, 차이가 없으면 클라이언트에서 구성된 UI를 활성화한다.
💡 Hydration의 중요성
Hydration에 의해 리액트의 상태 관리 기능이 활성화되어 사용자의 상호작용이 가능해진다.
또한, 서버에서 렌더링된 HTML을 사용하기 때문에 초기 로딩 속도가 빠르고, 클라이언트에서의 hydration 과정은 최소한의 자바스크립트를 사용하여 최적화된다.
이러한 결과로 서버에서 렌더링된 HTML은 검색 엔진에 쉽게 나타날 수 있어서 SEO에 유리한 결과로 이어진다.
💡 Hydration 주의점 - Mismatch
서버에서 렌더링된 HTML과 클라이언트에서 hydration된 HTML이 일치하지 않으면 리액트는 hydration mismatch 경고를 내보낸다.
이는 상태나 데이터가 클라이언트와 서버 간에 일치하지 않기 때문에 발생하는 것이다.
그래서 서버와 클라이언트에서 일관된 데이터를 사용해야 하고, 버튼 속에 버튼을 넣는 등의 구조적인 변경을 가할 때에도 mismatch 오류가 발생하게 된다.
리액트가 클라이언트에서 DOM을 재구성할 수 없기 때문에 mismatch 오류가 발생하면 반드시 해결하고 넘어가야 한다.
'코드잇 프론트엔드 스프린트' 카테고리의 다른 글
[위클리페이퍼] SEO의 의미와 개선할 수 있는 방법 (8) | 2024.10.04 |
---|---|
[위클리페이퍼] CORS 에러와 해결방법 (0) | 2024.10.04 |
[1차 협업프로젝트 TIL] 12일차 회고 (0) | 2024.09.06 |
[1차 협업프로젝트 TIL] 11일차 회고 (4) | 2024.09.05 |
[1차 협업프로젝트 TIL] 10일차 회고 (0) | 2024.09.04 |