나는 줄곧 CSR 만 사용해본 것 같다. 그런데 이번 프로젝트를 진행하면서 각 상황에 따라 다른 렌더링 방식을 사용해야해서 공부하게 되었고, 그 내용을 한번 적어보려한다. (공부한 걸 기록하는 건 참 좋은듯!!)
SPA(Single Page Application), 즉 ReactJS나 VueJS로 개발하면 CSR로 동작한다. CSR은 Client Side Rendering 으로 렌더링을 하는 주체 = 클라이언트(브라우저)
이다.
CSR이 일어나는 순서는 다음과 같다!
빈 HTML을 응답받기 -> HTML 파일 로딩 끝! -> 리소스 로딩 끝(JS, CSS 등등) -> 렌더링 실행
아, 참 그리고 빈 HTML이 로딩되는 동안에 사용자는 빈 페이지를 보게 된다.
CSR은 브라우저에 표기하기 위한 모든 코드를 클라이언트에서 다운받고, 실행하고 분석하여 표기하는 렌더링 방식이다. 따라서 CSR 방식을 적용해야하는 적합한 경우는 사용자 경험이 우선시되는 웹 애플리케이션일 때
필요하다.
CSR 방식의 장점과 단점으로는 무엇이 있을까?
장점 | 단점 |
---|---|
초기 렌더링 후 새로고침 없이 페이지 전환이 가능하다. | SEO가 좋지 않다. |
index.html을 한번만 요청하면 되기 때문에 서버 요청 부담이 적다. | 클라이언트에서 API 요청을 하므로 보안에 취약하다. |
동적으로 생성되는 콘텐츠는 캐싱되지 않으므로 CDN 캐시가 안된다. | |
자바스크립트 활성화가 필수이다. |
CSR의 단점으로 나온 SEO는 무엇일까?? SEO는 검색 엔진 최적화로, 쉽게 말하면 웹사이트 상위에 글을 노출시키는 것을 의미한다. 그렇다면 CSR 방식이 SEO가 좋지 않은 이유는 무엇일까?? CSR 방식은 초기에 빈 HTML 파일을 받아서 사용하므로 크롤러들이 어떤 내용이 있는지 확인이 어렵고, 페이지마다 meta 태그 등의 정보도 따로 설정이 안되기 때문
이다.
CDN이란 정적 컨텐츠를 전송하는데 쓰이는 분산된 서버 네트워크로 이미지, 비디오, CSS 등을 캐시할 수 있다.
SSR은 CSR과 반대되는 개념(?)인 것 같다. CSR이 클라이언트 주체
였다면, SSR은 서버 주체
이다. Server Side Rendering 으로서 서버에서 HTML을 생성하여 이를 응답해준다. 옛-날에 Spring과 JSP로 일체형 아키텍쳐 형태로 개발했던 시기에 사용된 렌더링 방식이다.
SSR은 사용자가 페이지를 요청할 때마다 HTML이 생성되므로 항상 최신 상태를 유지해야하는 웹페이지 혹은 차트
등에 적합하다.
SSR 방식의 장점과 단점으로는 무엇이 있을까?
장점 | 단점 |
---|---|
SEO가 좋다. | 요청마다 HTML을 생성하므로 느릴 수 있다. |
자바스크립트를 필요로 하지 않는다. | 너무 많은 요청으로 서버 과부하가 걸릴 수 있다. |
실시간 데이터를 보여준다. | 페이지 이동 시 화면이 깜빡인다. |
ReactJS에서 CSR 방식
으로는 useEffect
를 통해 데이터를 가져왔다면 Next.js
에서는 getServerSideProps
로 데이터를 불러온다.
export default function SSRPage({ users }: SSRPageProps) {
return (
<main>
<Users users={users} />
</main>
);
}
export const getServerSideProps: GetServerSideProps = async () => {
const res = await axios.get('https://eunniverse.com/api/users');
return {
props: { users: res.data },
};
};
SSG 는 SSR과 비슷하면서 좀더 발전된 개념같다! Static Site Generation으로 SSR처럼 렌더링의 주체 = 서버
이다. 하! 지! 만! SSR과 다르다. SSG는 클라이언트가 요청하는 시점이 아니라 빌드 시
에 페이지를 미리 생성한다. Next.js 에서 페이지를 생성할 때 기본적으로 적용되는 설정이다.
next build 명령어로 HTML 페이지를 생성
하고, CDN으로 캐싱되어 요청마다 HTML 재사용
한다. SSG는 빌드시에 페이지를 생성하므로, 주로 요청마다 동일한 정보로 반환하는 블로그 게시물과 같은 곳에서 사용되기 적합하다.
SSG 방식의 장점과 단점으로는 무엇이 있을까?
장점 | 단점 |
---|---|
SEO가 좋다. | 데이터가 정적이다. |
자바스크립트를 필요로 하지 않는다. | 사용자 별 정보 제공이 어렵다. |
CDN 캐시가 된다. | 실시간 데이터가 아니다. |
페이지 로딩시간이 빠르다. |
export default function SSGPage({ users }: SSGPageProps) {
return (
<main>
<Users users={users} />
</main>
);
}
export const getStaticProps: GetStaticProps = async () => {
const res = await axios.get('https://eunniverse.com/api/users');
return {
props: { users: res.data },
};
};
export const getStaticPaths = async () => {
return {
paths: [
{ params: { id: '1' } },
{ params: { id: '2' } },
{ params: { id: '3' } },
],
fallback: true,
};
};
export default function SSGPage({ users }: SSGPageProps) {
return (
<main>
<User user={user} />
</main>
);
}
// page의 path가 외부 데이터에 의존하는 경우 사용됨
export const getStaticProps: GetStaticProps = async ({ param }) => {
const id = param.id;
const res = await axios.get(`https://eunniverse.com/api/user/${id}`);
return {
props: { user: res.data },
};
};
ISR은 마치 SSG의 스케줄러 모드같달까? Incremental Static Regeneration 로 SSG처럼 빌드 시점에 페이지를 렌더링한 후 설정한 시간마다 페이지를 새로 렌더링한다. ISR은 일정 시간마다 알아서 페이지를 업데이트한다
는 점이 SSG 방식과 다르다. (SSG는 빌드 시점에만 렌더링!)
ISR은 사용자에게 빠르게 로드되는 정적 콘텐츠와 최신 정보를 제공할 수 있다는 이점이 있어서 뉴스 사이트나 이벤트 페이지 같은 곳에 적합한 렌더링 방식이다.
ISR 방식의 장점과 단점으로는 무엇이 있을까?
장점 | 단점 |
---|---|
데이터가 주기적으로 업데이트가 된다. | 실시간 데이터는 아니다. |
SEO가 좋다. | 데이터가 정적이다. |
자바스크립트를 필요로 하지 않는다. | 사용자 별 정보 제공이 어렵다. |
CDN 캐시가 된다. | |
페이지 로딩시간이 빠르다. |
export default function ISRPage({ users }: ISRPageProps) {
return (
<main>
<Users users={users} />
</main>
);
}
export const getStaticProps: GetStaticProps = async () => {
const res = await axios.get('https://eunniverse.com/api/users');
return {
props: { users: res.data },
revalidate: 30 // 렌더링 주기
};
};
SEO 적용이 크게 중요하지 않거나 데이터 pre-rendering이 필요없다면
CSR
정적 문서로 충분한 화면이면서 빠른 HTML 문서 반환이 필요하다면SSG
컨텐츠가 동적이지만 자주 변경되지 않는다면ISR
매 요청마다 화면이 달라지면서 서버 사이드로 렌더링을 하고자 한다면SSR
위의 내용을 살펴보면 각 렌더링 방식마다 장점과 단점이 명확히 구분된다. 그러면 이 렌더링 방식을 섞을 수 없을까?
해서 나온 하이브리드 렌더링
!!!
하이브리드 렌더링은 서버와 클라이언트의 자원을 최대한 활용하여 미디어 자료를 렌더링하는 방식이다. 예를 들어 홈페이지는 ISR로, 소개 페이지는 큰 변경이 없으므로 SSG로, 게시물 목록 페이지는 CSR/SSR을 활용해서 만들 수 있다.
pre-rendering 은 사용자에게 보여줘야하는 정보를 포함해 HTML로 만든 정적 페이지를 빠르게 보여주는 과정을 의미한다. pre-rendering 과정 후 react 라이브러리와 작성한 소스코드를 다운받아 컴포넌트가 렌더링된다.
즉, Hydration은 Server-Side에서 렌더링 된 정적 페이지(HTML)와 번들링 된 JS 파일을 클라이언트에게 보내면, Client-Side에서 HTML 코드와 JS(React) 코드를 서로 매칭시키는 과정
이다. JS 코드들이 DOM 요소 위에 물을 채우듯 필요로 하던 요소들을 채운다하여 붙여진 이름이라고 한다.
그럼 결국 2번 렌더링된다는 이야기인데, 비효율적이지 않을까?
결론부터 말하면 아니다
. 왜냐하면!! pre-rendering된 문서는 굉장히 가벼운 파일이라서 빠르게 로드되며, DOM 요소에 JS 속성을 매칭시킬 뿐 웹페이지를 다시 그리는 paint() 함수를 호출하지 않기 때문
이다.