SSR이란?
SPA
- 렌더링, 라우팅에 필요한 대부분의 기능을 서버가 아닌 브라우저의 자바스크립트에 의존하는 방식
- 최초에 서버에서 최소한의 데이터를 불러온 이후 이미 가지고 있는 JS 리소스와 브라우저 API 기반으로 동작
- 최초 첫 페이지에 데이터를 불러온 후 페이지 전환은 history.pushState, replaceState로 이뤄진다.
- body에는 아무런 내용이 없다.
스택의 종류
- LAMP
- Linux, Apache, MySQL, PHP/Python
- JAM
- JS, API, Markup
- MEAN
- MongoDB, Express.js, Angular.js, Node.js
새로운 패러다임의 웹서비스를 향한 요구
- 웹페이지를 불러오는데 필요한 부분을 사용자에게 전가해도 기기나 환경의 발전으로 괜찮을거라 생각
- 그에 따른 JS 리소스의 크기와 양도 증가
- 하지만 기기의 발전에도 사용자 체감(로딩 속도 등)은 여전히 크게 개선되지 않았다.
SSR
- 최초에 사용자에게 보여줄 페이지를 서버에서 렌더링해 빠르게 사용자에게 화면을 제공하는 방식
- SPA는 사용자에게 제공되는 JS 번들에서 렌더링 담당 → SSR은 서버에서!
- 장점
- 최초 페이지 진입(FCP)이 빠르다. → 서버에서의 HTTP 요청, HTML 그리는 작업이 서버가 더 빠르다
- SEO → 로봇은 HTML을 가져가 OG, meta 정보로 검색 엔진에 저장하기 때문
- 누적 레이아웃 이동(CLS)이 적다
- 사용자에게 페이지를 보여준 후 뒤늦게 어떤 HTML 정보가 추가, 삭제되어 마치 화면이 덜컥거리는 것과 같은 부정적인 사용자 경험 → API 로딩에 따른 레이아웃 이동
- 사용자의 디바이스 성능에 비교적 자유롭다
- 보안에 조금 더 안전하다
- 인증과 같은 민감한 작업을 서버에서 수행
- 단점
- 소스코드 작성 시 서버 고려
- 브라우저 전역 객체인 window, sessionStorage 등
- 적절한 서버 구축 → 서버가 모든걸 담당하기 때문에 가용량, 복구 전략, 요청 분산 등 고려 필요
- 서비스 지연에 따른 문제
- 소스코드 작성 시 서버 고려
- 여러 페이지 전환 기법
- Paint Holding: 같은 출처에서 라우팅이 일어날 경우 이전 페이지의 모습을 잠깐 보여주는 기법
- back forward cache: 브라우저 앞으로 가기, 뒤로가기 실행 시 캐시된 페이지 보여주는 기법
- Shared Element Transitions: 페이지 라우팅 시 컨텍스트를 유지해 부드럽게 전환하는 기법
- 최근의 SSR은 SPA의 장점을 흡수한 방식이다.
- 최초 웹사이트 진입 시에는 SSR로 서버에서 완성된 HTML 제공
- 이후 라우팅에서는 서버에서 내려받은 JS를 바탕으로 SPA처럼 동작
SSR을 위한 react API
renderToString
- 인수로 넘겨받은 리액트 컴포넌트를 렌더링해 HTML 문자열로 변환하는 함수
- 인수는 오직 리액트 컴포넌트
- 클라이언트에서 실행되는 JS 코드를 포함시키거나 렌더링하는 역할 x → 빠른 HTML 제공이 목적
- 사용자 인터랙션은 이후 진행 (최초 HTML을 빠르게 그려주는게 목적)
renderToStaticMarkup
- renderToString과 다른 점은 루트 요소에 data-reactroot과 같은 리액트에서만 사용하는 추가적인 DOM 속성을 만들지 않는다는 점
- data-reactroot은 hydrate 함수에서 루트를 식별하는 기준점으로 사용
- 순수한 HTML 리턴 → 이 경우 리액트에서 제공하는 useEffect와 같은 브라우저 API 사용 불가
- 따라서 블로그 글이나 상품 약관 정보와 같이 아무런 브라우저 액션이 없는 정적인 내용만 필요한 경우 유용
renderToNodeStream
- 브라우저에선 사용 불가
- 함수 결과물 : Node.js의 ReadableStream → utf-8로 인코딩된 바이트 스트림
- 응답으로 오는 HTML을 여러 청크로 분할해 조금씩 전달
- 대부분의 널리 알려진 리액트 SSR 프레임워크는 이걸 채택하고 있다
renderToStaticNodeStream
- hydrate가 필요없는 순수 HTML을 스트림 방식으로 렌더
hydrate
- renderToString, renderToNodeStream으로 생성된 HTML 콘텐츠에 JS 핸들러나 이벤트를 붙이는 역할
- render 함수
- 컴포넌트와 HTML 요소를 인수로 받는다
- 두 정보를 바탕으로 HTML 요소에 해당 컴포넌트를 렌더링하며, 여기에 이벤트 핸들러를 붙이는 작업까지 모두 한 번에 수행
- hydrate
- 이미 렌더링된 HTML이 있다는 가정하에 작업 수행
- 렌더링된 HTML을 기준으로 이벤트를 붙이는 작업만 실행
- 따라서 서버에서 제공해준 HTML이 클라이언트의 결과물과 같지 않을 때 다음 에러 노출
- Warning: Expected server HTML to contain a matching …
Next.js 톺아보기
next/link
- SSR이 아닌 클라이언트에서 필요한 JS만 불러온 뒤 라우팅하는 CSR 방식으로 동작
- 자연스러운 라우팅 제공
- 속성
- scroll: 페이지 이동 시 스크롤 유지 여부
- replace: 브라우저 기록을 URL에 추가하는 대신 현재 기록을 대체
- prefetch: link 컴포넌트가 뷰포트에 보이면 해당 경로를 미리 페칭할지 말지 여부 결정
getStaticProps
- 정적 페이지
- 미리 빌드해놓고 빠르게 렌더링
- 블로그 글이나 약관 같이 단순한 콘텐츠를 빠르게 제공하기만 하는 경우
getServerSideProps
- 서버에서 실행
- 클라이언트에서만 실행 가능한 변수, 함수, 라이브러리 실행 불가
- 사용자가 매 페이지를 호출할 때마다 실행
- 이 실행이 끝나기 전까지는 사용자에게 어떠한 HTML도 보여줄 수 없다.
getInitialProps
- 때에 따라 서버, 클라이언트 모두 실행
- getServerSideProps, getStaticProps 나오기 이전에 사용하던 페이지 데이터 페칭 수단
- _app.tsx와 같이 일부 페이지에서는 getInitialProps밖에 사용 불가
scss
- scss에서 제공하는 variable을 컴포넌트에서 사용하고 싶다면 export 문법을 사용하면 된다.
반응형
'Programming > 13. Book' 카테고리의 다른 글
모던 리액트 Deep Dive - 10장 (0) | 2024.03.02 |
---|---|
모던 리액트 Deep Dive - 5장 (0) | 2024.03.02 |
모던 리액트 Deep Dive - 3장 (0) | 2024.03.02 |
모던 리액트 Deep Dive - 2장 (0) | 2024.03.02 |
02. 데이터베이스 개론 요약 (4~6장) (0) | 2022.12.04 |
댓글