\(@^0^@)/
[TIL] SSR, CSR, SSG (feat.Next.js) 본문
프리온보딩을 하며 Next.js를 처음 접했는데 우리 팀이 선택했던 과제는 페이지가 하나인 프로젝트여서 Next.js의 맛을 전혀 느낄 수가 없었다.
그래서 선택하지 않은 좀 더 큰 규모였던 과제를 혼자 차근차근 만들면서 Next.js를 공부해보려 한다.
강의를 듣고 있는 중인데, Next.js하면 빠질 수 없는 CSR과 SSR를 한번 짚고 넘어가야 할 것 같아서 프로젝트 들어가기 전에 후딱 정리해보자!
💡 SSR이란?
Server Side Rendering의 약자로, 말 그대로 서버 측에서 렌더링 하는 방식.
브라우저에서 서버로 컨텐츠를 요청하면, 서버에는 즉시 페이지에 필요한 데이터를 얻어와 모두 삽입하고 CSS까지 모두 적용해서 렌더링 준비를 마친 HTML, JS code를 브라우저에 전달한다. 전달받은 브라우저는 HTML, CSS를 렌더 하고, JS code 다운로드하여 HTML에 JS로직을 연결한다.
따라서 데이터가 달라지거나 자주 바뀌어서 미리 만들어두기 어려운 페이지에 적합.
📍 SSR방식의 MPA
MPA란? Multi Page Application의 약자로, 여러 개의 페이지로 구성된 웹 애플리케이션이다.
새로운 페이지를 요청할 때마다 서버에서 렌더링 된 정적 리소스(HTML, CSS, JavaScript)가 다운로드된다.
페이지 이동하거나 새로고침 하면 전체 페이지를 다시 렌더링 하는 전통적인 웹 페이지 구성 방식.
👍 SSR 장점
- 짧은 첫 로딩
- 서버에서 이미 렌더링 해서 클라이언트 쪽으로 가져오기 때문에, 로딩이 짧을 수밖에 없음.
- 그러나 클라이언트가 JS 파일을 모두 다운로드하고 적용하기 전 까지는 각각의 기능들은 동작하지 않음.
- 유리한 SEO 최적화
- MPA는 완성된 형태의 HTML 파일을 서버로부터 전달받는다. 따라서 검색엔진이 페이지를 크롤링하기에 적합.
👎 SSR 단점
- 새로운 페이지를 이동하면 ‘깜빡’ 인다. (UX)
- 새로운 페이지를 요청할 때마다 리로딩(새로고침) 발생하여 전체 페이지를 다시 렌더링 한다.
- 서버 과부하
- 특히 사용자가 많은 제품일수록 사용자가 클릭할 때마다 서버에서 필요한 데이터를 가지고 와서 HTML을 만들어야 하므로 서버에 부담이 크다.
- TTV(Time To View)와 TTI(Time To Interact)의 간격이 있음
- 로딩은 빠르지만, HTML, CSS를 렌더 한 껍데기에 불과하기 때문에 실제로 클라이언트 측 JS가 실행되고 JS 로직이 모두 연결될 때까지 사용자 입력에 응답하지 않기 때문.
🔍 SEO란?
검색 엔진 최적화 (Search Engine Optimization)의 약자로,
구글, 네이버와 같은 검색엔진들은 서버에 등록된 웹사이트를 돌아다니며 웹사이트의 HTML의 문서들을 분석해서
우리가 검색을 통해 웹사이트를 연결하도록 돕는 최적화 프로세스이다.
💡 CSR이란?
Client Side Rendering의 약자로, 말 그대로 클라이언트 측에서 렌더링 하는 방식.
유저가 웹사이트에 방문하여 콘텐츠를 요청하면, 그때 서버에서 빈 뼈대만 있는 HTML 파일들을 응답으로 보내준다.
브라우저가 연결된 JS링크를 통해 서버로부터 다시 JS 파일을 다운로드하고, 그 JS 파일들을 이용해 동적으로 페이지를 (DOM) 생성하여 브라우저에 띄워준다.
📍 CSR방식의 SPA
SPA란? Single Page Application의 약자로, 하나의 페이지로 구성된 웹 애플리케이션으로,
어떤 웹 사이트의 전체 페이지를 하나의 페이지에 담아 동적으로 화면을 바꿔가며 표현하는 것이 SPA이다.
뭔가를 클릭하거나 스크롤하면, 상호작용하기 위한 최소한의 요소만 변경이 일어난다.
페이지 변경이 일어난다고 보이는 것 또한 최초 로드된 자바스크립트를 통해 미리 브라우저에 올라간 템플릿만 교체되는 것으로 MPA와는 반대 개념이라고 할 수 있다.
👍 CSR 장점
- 빠른 구동 속도
- 초기 로딩 이후 페이지 일부를 변경할 때, 서버에 해당 데이터만 요청하기 때문에 구동 속도가 빠름.
- 낮은 서버 부하
- 서버에서 빈 뼈대 HTML, 연결된 JS 링크만 넘겨주는 역할만 수행하기 때문
- 빠른 반응 속도, 우수한 UX
- 클라이언트 측에서 연산, 라우팅 등을 모두 직접 처리하기 때문
👎 CSR 단점
- 느린 초기 로딩 속도.
- JS파일들을 모두 다운로드하고 동적으로 DOM을 생성하는 시간을 기다려야 함
- 페이지 캐싱이 잘 안 된다. (server에서 올 땐 그냥 빈 페이지고 그 뒤에 JS가 돌아야만 페이지를 생성)
- 불리한 SEO 최적화
- 서버에서 빈 뼈대 HTML을 넘겨주기 때문에 웹 크롤링을 할 때 텅텅 비어있어, 검색엔진이 색인을 할 만한 콘텐츠가 존재하지 않는다.
- 서버에서 빈 뼈대 HTML을 넘겨주기 때문에 웹 크롤링을 할 때 텅텅 비어있어, 검색엔진이 색인을 할 만한 콘텐츠가 존재하지 않는다.
💊 CSR의 단점 보완 방법
- 초기 로딩 속도 보완
- code splitting, tree-shaking, chunk 분리를 통해 JS 번들 크기를 줄여서 초기 DOM 생성 속도를 줄인다.
- SEO 개선
- pre-rendering : 각 페이지에 대한 HTML 파일을 미리 생성해둔 뒤 서버에서 요청할 때 보여줌. (라이브러리나 플러그인 설치)
- SPA에 SSR이나 SSG를 도입
- without 프레임워크 : Express.js로 별도의 서버를 직접 운영
- with 프레임워크 : React - Next.js, Gatsby / Vue - Nuxt
- Next.js : 리액트에서 SSR이나 SSG를 사용할 수 있게 해주는 프레임워크, 페이지별로 SSR, SSG 선택 가능
- Gatsby : SSG에 최적화된 리액트 기반 정적 페이지 생성 프레임워크로 CSR, SSR, 레이지 로딩 등도 지원하고 다양한 플러그인들도 제공.
💡 SSG란?
Static Site Generation의 약자로, 서버에서 HTML 파일들을 보내준다는 측면에서는 SSR과 비슷하지만,
SSG는 페이지들을 서버에 모두 만들어둔 뒤, 요청 시 해당 페이지를 응답하는 것이기 때문에 바뀔 일이 거의 없어 캐싱해두면 좋은 페이지에 적합하다.
✨ Next.js 란?
CSR과 SSR의 장점을 모은 Next.js 프레임워크
SSR을 React로 할 수 있음. (처음에 server에서 html 태그를 받아올 수 있다는 뜻!)
그렇기에, CSR - SPA의 단점인 2번 페이지 캐싱, 3번 SEO의 문제를 해결할 수 있으며
Next.js에서 SSG(Static Site Generation)이라는 기능을 사용하여 React로 만든 Html 파일을 캐싱을 해준다.
또한 CSR - SPA의 장점인 빠른 속도와 효율적인 코딩도 당연히 갖춰졌음.
처음에는 SSR로 html 코드들을 불러오고 그 뒤에 Link 등을 통해 다른 사이트로 이동할 때는 CSR을 사용하면서
CSR과 SSR의 장점을 모두 이용할 수 있음.
🤔 서비스 성격에 따른 CSR, SSR, SSG 사용기준
- CSR : 사용자와의 상호작용이 많고, 대부분이 고객 개인정보로 이루어진 페이지들이라 검색 엔진에 노출될 필요가 없을 경우.
- SSR : 누구에게나 항상 같은 내용을 보여주고, 업데이트를 자주 하는 경우. (ex. 회사 홈페이지)
- SSG : 누구에게나 항상 같은 내용을 보여주지만, 업데이트를 자주 하지 않는 경우.
- Universal : 사용자에 따라 페이지 내용도 달라지고, SEO 최적화, 빠른 인터랙션이 중요하며 화면 깜빡임을 지양하는 경우. ( CSR + SSR )
https://www.youtube.com/watch?v=hvkeK71WXb8
https://www.youtube.com/watch?v=YuqB8D6eCKE
https://www.huskyhoochu.com/what-is-spa/
'TIL' 카테고리의 다른 글
[TIL] json-server를 활용한 페이지네이션 구현시 고려해야할 사항 (0) | 2022.04.15 |
---|---|
[TIL] 간단한 server와 SSR, SSG Test (0) | 2022.03.27 |
[TIL] 기억해두고 싶은 TS 문법들 (0) | 2022.02.05 |
[TIL] Typescript 쓰는 이유와 설치방법 (0) | 2022.02.04 |
[TIL] 성능 최적화를 위한 방법들 (useMemo, useCallback) (0) | 2022.02.04 |