단순하게 개념을 습득하는건 쉬웠는데 작동원리까지 확실하게 이해하려니 약간 헷갈리는 부분이 있었다.
아무튼, Hydration에 대해서 설명하려면 먼저 렌더링 방식의 차이부터 이해해야 하는데, 이건 내가 예전에 정리해둔 글이 있으니까 링크를 첨부하도록 하겠다.
https://hjinn0813.tistory.com/100
어플리케이션(SPA, MPA) 렌더링(CSR, SSR, SSG) 검색엔진 최적화(SEO)
Next.js 공부하기 전에 기본적인 개념정리가 필요할 것 같아서 기록하는 글.아래에 언급될 기초적인 내용들에 대해서 예전에 블로그에 정리해둔게 있어서 링크도 첨부한다!🙂※ 서버와 클라이언
hjinn0813.tistory.com
Next.js는 기본적으로 모든 컴포넌트와 페이지를 SSR 방식으로 렌더링한다.
1. 사용자가 페이지에 접속한다.
2. 서버는 다운받을 파일들 체크하고 컴파일하여 HTML을 미리 만든다.
3. HTML이 클라이언트에 전달되면서 즉시 렌더링되어 사용자에게 보여진다. 근데 JS가 없는 '빈 껍데기' 상태여서 작동은 불가능하다.
Hydration
정적인 HTML만 렌더링된 상태에서, 클라이언트가 JS를 다운로드하고 컴파일해서 HTML과 연결시키는 과정.
즉, 렌더링된 정적 HTML과 동작에 필요한 JS를 서버가 보내면, 클라이언트가 HTML과 JS를 매칭시켜서 동적인 HTML로 만들어내는 과정을 의미한다.
JS가 정적인 DOM 요소 위에 물을 채우듯이 필요한 요소들을 채운다고 하여 붙여진 이름이다.
https://hjinn0813.tistory.com/107
Next.js의 SPA과 SSR, 정적자원 활용, CSS
Next.js와 SPA, SSRnpm run dev로 페이지를 열어놓은 상태에서, [개발자 도구 > Run Command] 클릭하고 Disable JavaScript 클릭하면 JS가 꺼진다. 이 실험을 통해 알 수 있는 것은, React는 JS 기술이기 때문에
hjinn0813.tistory.com
'생활코딩' 강의에서 나왔던 부분이 '노마드코더' 강의에서도 나와서 다시 한번 정리하자면,
React는 JS 기술이라서 JS가 없으면 웹 페이지 렌더링이 아예 안 되고, Next.js는 서버(.next 폴더)에서 정적인 HTML 페이지부터 만들어서 보여주는 "SSR 방식"으로 렌더링이 되기 때문에 JS가 없어도 렌더링이 된다. Next.js는 HTML을 응답한다.
→ 그래서 정적인 HTML부터 렌더링되어 사용자에게 보여진 후에, JS가 다운로드+컴파일되어 "뼈대만 있어 앙상한" HTML에 들어가서 각자의 위치를 찾아가는게 Hydration.
Next.js의 컴포넌트 렌더링 방식
Next.js 프로젝트에서 컴포넌트를 렌더링하는 방식을 이해하기 위해서는 서버, 클라이언트 컴포넌트의 차이부터 알고 있어야 한다. 이미 며칠 전에 강의를 들으면서 기록해둔 내용이 있어서 일단 링크 첨부.
※ Next.js와 컴포넌트 - https://hjinn0813.tistory.com/108
Next.js와 백엔드, 글 목록 가져오기 (서버, 클라이언트 컴포넌트)
Next.js와 백엔드루트의 layout.js에 Link 태그로 연결한 코드를 백엔드 구축해서 동적으로 보여주기 실습→ Next.js를 순수하게 백엔드로 사용하려면, 라우트 핸들러 기능을 활용하면 된다.
hjinn0813.tistory.com
서버 컴포넌트 (Server Components) |
- 서버에서만 렌더링된다. - 서버에서 완전히 렌더링된 HTML을 클라이언트로 보내기 때문에 Hydration이 필요없다. - 서버에서만 실행되므로 상태 관리나 이벤트 핸들러 등을 포함할 수 없다. |
클라이언트 컴포넌트 (Client Components) |
- 파일 맨 위에 "use client"라는 키워드를 넣어 클라이언트 컴포넌트로 지정한다. - 서버에서 렌더링된 후 클라이언트에서 Hydration 과정이 필요하다. - 상태 관리나 이벤트 핸들링과 같은 클라이언트 측 로직을 포함할 수 있다. |
Next.js 프로젝트에서는 서버 컴포넌트와 클라이언트 컴포넌트 모두 서버에서 HTML을 준비하기 때문에, 서버 사이드 렌더링(SSR)이 모든 컴포넌트에서 발생할 수 있다. 하지만 서버 컴포넌트는 JS와 연결되지 않아서, Hydration은 클라이언트 컴포넌트에만 해당된다.
렌더링만 되고 Hydration 될 필요가 없으면 JS를 다운받을 일도 없기 때문에, 페이지 로딩 속도가 더 빨라져서 사용자는 더 좋은 UX를 경험할 수 있다.
사용자와 상호작용을 하려면 JS가 필요하니까 → 클라이언트 컴포넌트로 만든다.
정보만 보여주면 되는, 상호작용이 필요없는 요소는 → 서버 컴포넌트로 만든다.
컴포넌트 불러오기 (서버 ↔ 클라이언트)
서버 컴포넌트에서는 클라이언트 컴포넌트를 자유롭게 불러올 수 있다. 정적인 HTML이 서버에서 생성되고 나면, 클라이언트 컴포넌트는 클라이언트 측에서 JS를 HTML과 연결시키는 Hydration을 진행한다.
클라이언트 컴포넌트는 서버 컴포넌트를 직접 불러올 수 없다. 서버 컴포넌트는 서버에서 HTML로 렌더링되면 클라이언트 측에서는 단지 정적 HTML로서 존재하게 된다. 쉽게 말해 서버 컴포넌트는 렌더링이 끝나면 더는 할 일이 없다. 하지만 클라이언트 컴포넌트는 서버에서 렌더링된 이후에도 클라이언트 측에서 Hydration 과정을 거쳐야 한다. 그래서 서버 컴포넌트가 클라이언트 컴포넌트 안에 있으면 직접 다룰 수 없다.
원래는 이렇게 불가능했는데, 최신 버전의 Next.js에서는 서버 컴포넌트를 prop로 넘겨준다면 클라이언트 컴포넌트에서 전달받아 사용하는게 가능하다. 만약 서버 컴포넌트를 prop로 클라이언트 컴포넌트에 넘겨준다면 작동원리는,
- 서버 컴포넌트가 먼저 서버에서 미리 렌더링
- HTML로 변환되어 prop를 통해 클라이언트 컴포넌트에 전달됨
- 클라이언트 컴포넌트는 서버 컴포넌트가 만든 HTML을 prop로 받아서 최종 HTML 렌더링
- 전체 렌더링이 끝나면 Hydration 진행
'💻 Frontend > Next.js' 카테고리의 다른 글
Next.js 데이터 병렬 요청, Suspense, 에러 핸들링 (0) | 2024.08.27 |
---|---|
Next.js 데이터 패치, 로딩 컴포넌트, 스트리밍 (0) | 2024.08.27 |
Next.js 수동 설치 (nomadcoder) (0) | 2024.08.24 |
Next.js와 환경변수 (0) | 2024.08.22 |
Next.js와 글 삭제, 수정 (0) | 2024.08.22 |