20.1 서버 사이드 렌더링의 이해
- 서버 사이드 렌더링은 UI를 서버에서 렌더링하는 것을 의미한다.
- 리액트 프로젝트는 기본적으로 클라이언트 사이드 렌더링을 하고 있다.
- 클라이언트 사이드 렌더링은 UI 렌더링을 브라우저에서 모두 처리하는 것. 즉, 자바스크립트를 실행해야 만든 화면이 사용자에게 보인다.
- 즉, 이 페이지는 처음에 빈 페이지라는 뜻, 그 이후에 자바스크립트가 실행되고 리액트 컴포넌트가 렌더링 되면서 보이는 것이다.
- 서버 사이드 렌더링을 구현하면 사용자가 웹 서비스에 방문했을 때 서버 쪽에서 초기 렌더링을 대신 해준다. 그리고 사용하자가 html을 전달받을 때 그 내부에 렌더링된 결과물이 보인다.
1️⃣ 서버 사이드 렌더링의 장점
- 구글, 네이버, 다음 등의 검색 엔진이 만든 웹 애플리케이션의 페이지를 원활하게 수집할 수 있다.
- 리액트로 만든 SPA는 검색엔진 크롤러 봇처럼 자바스크립트가 실행되지 않는 환경에서는 페이지가 제대로 나타나지 않는다.
- 따라서 서버에서 클라이언트 대신 렌더링을 해 주면 검색 엔진이 페이지의 내용을 제대로 수집해 갈 수 있다.
- 구글 검색 엔진은 다른 검색 엔진과 달리 검색 엔진에서 자바스크립트를 실행하는 기능이 탑재되어 있으므로 제대로 페이지를 크롤링해 갈 때도 있지만 모든 페이지에 대해 자바스크립트를 실행해주지는 않는다
- 서버 사이드 렌더링이 구현되지 않은 웹 페이지에 사용자가 방문하면, 자바스크립트가 로딩되고 실행될 때까지 사용자는 비어 있는 페이지를 보며 대기해야 하고 API까지 호출해야 된다면 대기 시간이 더욱 길어진다.
- 서버 사이드 렌더링을 구현한 웹 페이지라면 자바스크립트 파일 다운로드가 완료되지 않은 시점에서도 html상에 사용자가 볼 수 있는 콘텐츠가 있기 때문에 대기 시간이 최소화되고 사용자 경험도 향상 된다.
2️⃣ 서버 사이드 렌더링의 단점
- 브라우저가 해야 할 일을 서버가 대신 처리하는 것이므로 서버 리소스가 사용된다.
- 갑자기 수많은 사용자가 동시에 웹 페이지에 접속하면 서버에 과부하가 발생할 수 있다. 따라서 사용자가 많은 서비스라면 캐싱과 로드 밸런싱을 통해 성능을 최적화해 주어야 한다.
- 프로젝트의 구조가 좀 더 복잡해질 수 있다.
- 데이터 미리 불러오기, 코드 스플리팅과의 호환 등 고려해야 할 사항이 더 많아져서 개발이 어려워질 수도 있다.
3️⃣ 서버 사이드 렌더링과 코드 스플리팅 충돌
- 별도의 호환 작업없이 두 기술을 함께 적용하면, 아래와 같은 흐름으로 페이지에 깜빡임이 발생한다.
1. 서버 사이드 렌더링된 결과물이 브라우저에 나타난다.
2. 자바스크립트 파일 로딩 시작
3. 자바스크립트가 실행되면서 아직 불러오지 않은 컴포넌트를 null로 렌더링한다.
4. 페이지에서 코드 스플리팅된 컴포넌트들이 사라진다.
5. 코드 스플리팅된 컴포넌트들이 로딩된 이후 제대로 나타난다.
20.3 서버 사이드 렌더링 구현하기
- 서버 사이드 렌더링을 구현하려면 웹팩 설정을 커스터마이징해 주어야 한다.
- CRA로 만든 프로젝트에서는 웹팩 관련 설정이 기본적으로 모두 숨겨져 있어 yarn eject 명령어를 실행하여 밖으로 꺼내주어야 한다.
- 서버 사이드 렌더링을 구현하면 첫 번째 렌더링은 서버를 통해 하지만, 그 이후에는 브라우저에서 처리한다.
20.4 데이터 로딩
- 데이터 로딩을 한다는 것은 API 요청을 의미한다.
- 일반적인 브라우저 환경에서는 API를 요청하고 응답을 받아 와서 리액트 state 혹은 리덕스 스토어에 넣으면 자동으로 리렌더링하니까 큰 걱정은 없다.
- 하지만 서버의 경우 문자열 형태로 렌더링하는 것이므로 state나 리덕스 스토어의 상태가 바뀐다고 해서 자동으로 리렌더링되지 않는다. 그 대신 renderToString 함수를 한 번 더 호출해 주어야 한다.
- 서버에서는 componentDidMount 같은 라이프사이클 API도 사용할 수 없다.
- 서버 사이드 렌더링을 할 때는 이미 있는 정보를 재요청하지 않게 처리하는 작업이 중요하다.
1️⃣ PreloadContext
- PreloadContext는 서버 사이드 렌더링을 하는 과정에서 처리해야 할 작업들을 실행하고 만약 기다려야 하는 프로미스가 있다면 프로미스르 수집한다.
- 모든 프로미스를 수집한 뒤, 수집된 프로미스들이 끝날 때까지 기다렸다가 그 다음에 다시 렌더링하면 데이터가 채워진 상태로 컴포넌트들이 나타나게 된다.
- renderToStaticMarkup은 리액트를 사용하여 정적인 페이지를 만들 때 사용한다.
- 이 함수로 만든 리액트 렌더링 결과물은 클라이언트 쪽에서 HTML DOM 인터랙션을 지원하기 힘들다.
- 이 함수를 사용하는 이유는 Preloader로 넣어 주었던 함수를 호출하기 위해서, 또 이 함수의 처리 속도가 renderToString 보다 좀 더 빠르기 때문이다.
2️⃣ redux-saga
- redux-thunk를 사용하면 preloader를 통해 호출한 함수들이 Promise를 반환하지만, redux-saga를 사용하면 Promise를 반환하지 않기 때문에 추가 작업이 필요하다.
20.5 서버 사이드 렌더링과 코드 스플리팅
- 리액트에서 공식적으로 제공하는 코드 스플리팅 기능인 React.lazy와 Suspense는 서버 사이드 렌더링을 아직 지원하지 않는다.
20.6 서버 사이드 렌더링의 환경 구축을 위한 대한
1️⃣ Next.js
- Next.js라는 리액트 프레임워크를 사용하면 작업을 최소한의 설정으로 간단하게 처리할 수 있지만 몇 가지 제한이 있다.
- 리액트 라우터와 호환되지 않기 때문에 이미 작성된 프로젝트에 적용하는 것은 매우 까다롭다.
- 리액트 라우터는 컴포넌트 기반으로 라우트를 설정하는 반면에 Next.js는 파일 시스템에 기반하여 라우트를 설정한다. 컴포넌트 파일의 경로와 파일 이름을 사용하여 라우트를 설정하는 것
- 코드 스플리팅, 데이터 로딩, 서버 사이드 렌더링을 가장 쉽게 적용하고 싶다면 Next.js를 사용하는 것이 좋다.
- 하지만, 리액트 라우터의 라우팅 방식을 더 좋아하거나, 기존의 프로젝트에 적용해야 하거나, 혹은 작동 원리를 제대로 파악하면서 구현하고 싶다면 직접 구현하는 것이 가장 좋다.
2️⃣ Razzle
- Razzle 또한 Next.js처럼 서버 사이드 렌더링을 쉽게 할 수 있도록 해 주는 도구이며, 프로젝트 구성이 CRA와 매우 유사하다는 장점이 있다.
- 프로젝트의 구조를 마음대로 설정할 수 있으며, 리액트 라우터와도 잘 호환된다.
- Loadable Components를 적용하는 것이 불가능하지는 않지만, 최신 버전의 Loadable Components가 기본 설정으로는 작동하지 않아서 적용하기가 까다롭다.
#출처 : 리액트를 다루는 기술(저자 : 김민준 VELOPERT)
'Front-End, CS 스터디 > [도서] 리액트를 다루는 기술' 카테고리의 다른 글
[도서] 리액트를 다루는 기술 #컴포넌트 성능 최적화 (0) | 2022.11.07 |
---|---|
[도서] 리액트를 다루는 기술 #Hooks (0) | 2022.11.05 |
[도서] 리액트를 다루는 기술 #컴포넌트 반복 (0) | 2022.10.28 |
[도서] 리액트를 다루는 기술 #리액트 없이 쓰는 리덕스 (0) | 2022.10.18 |
[도서] 리액트를 다루는 기술 #리덕스 개념 미리 정리하기 (0) | 2022.10.18 |