서론
처음 회사에 Next.js 개발 방식을 도입했을 때, 관련 렌더링의 종류를 모두 조사한 적이 있었다. 사실 그때는 자료조사를 하면서도 완전히 이해하지는 못했는데, 다시 하나하나 적어내려가며 이해가 되었다.
사실 이 내용을 적을까 말까 고민을 했는데, Server component와 App router 방식이 적용 된 이후 ISR는 더이상 언급이 사라졌고, SSR은 흔히 우리가 생각하는 '서버에서 렌더링 하는 컴포넌트' 개념과 혼용의 가능성이 있어 Dynamic Rendering으로 명칭이 변경되었기 때문이다.
그래서 다시 한번 과거 렌더링 방식을 정리하고 그게 어떻게 변경되었는지를 명시하려 한다.
본론
Client Side Rendering ( CSR )
특징
- 렌더링 하는 주체가 클라이언트 (브라우저)
- 보통 리액트로만 프로젝트를 개발했을 경우 그 프로젝트는 CSR
- 브라우저에서 페이지를 요청 시 서버에서 body 부분이 빈 html을 전송. 그 다음 클라이언트는 React 라이브러리 소스 파일, React로 작성된 Javascript코드를 다운로드.
- 이 과정에서 첫 로딩 과정이 매우 길다는 특징이 있음
장점
- 첫 로딩 이후에는 매우 빠른 어플리케이션 진행을 보여줌 ( 빠른 UX 제공 )
- 서버 작업량이 줄어들어 서버 부하 감소
단점
- 첫 페이지 로딩 시간( TTV : Time to view , FCP : First contentsful paint )이 길다.
- 자바스크립트 활성화가 필수 (브라우저가 JS 비활성했을 경우 서비스 이용불가)
- SEO 최적화의 한계가 있고, 까다로움 (검색엔진 크롤러가 컨텐츠 크롤링 불가)
- 보안에 취약 (클라이언트가 대부분의 서비스 처리를 하기 때문에)
- CDN(Content Delivery Network)에 캐시가 되지 않아 타국의 서비스는 느린 응답속도
- CDN이란? : 서버가 타국에 있을 경우 유저와 가까운 지역에서 데이터를 빠르게 응답받을 수 있게 하는 클라우드 서버
사용 예시
- Next.js에서는 컴포넌트 코드 상단에 'use client'라고 붙여서 클라이언트 컴포넌트를 만들 수 있는 것은 아님
- App router 특성상 App 폴더 내에 있는 모든 컴포넌트가 React의 server component 취급받기 때문인데, 리액트와 달리 이 경우 화면에 static하게 적용된 마크업의 경우 여전히 서버측에서 미리 렌더링하고 캐시를 해두기 때문
- 이를 해결하기 위해 다음과 같은 예시대로 클라이언트 컴포넌트를 구현
- 말 그대로 useState와 useEffect를 사용해서 모든 JS가 다운로드 되고, 로드되기 전에는 아무런 컴포넌트를 보여주지 않는 방식
'use client';
import React, { useState, useEffect } from 'react';
export default function TestPage() {
const [isLoaded, setIsLoaded] = useState(false);
useEffect(() => {
setIsLoaded(true);
}, []);
if (!isLoaded) {
return null;
}
return (
<div>
<h1>클라이언트 사이드 렌더링 적용!</h1>
</div>
);
}
Static Site Generation ( SSG )
특징
- 렌더링하는 주체가 서버
- CSR의 장점은 가져가되 배포할때는 정적인 페이지로 배포하기 위해 나온 개념
- 렌더링을 언제 실시하는지에 따라 ISR, SSR과 구분 가능
- SSG는 프로젝트를 빌드할 때 렌더링을 실시
- 빌드 직후 html 페이지는 동적인 페이지가 아니라 정적인 페이지로 구성
- 정적인 페이지 특성상 회사소개와 같은 데이터가 가변적이지 않은 서비스에 적합
- Next.js의 App router 방식을 따르면 보통 이 렌더링 방식을 채택
- 'use client'를 사용하지 않은 컴포넌트는 js파일을 클라이언트로 따로 전송하지 않고 모두 서버에서 캐싱
- 'use client'를 사용한 컴포넌트는 마크업과 JSON만 캐싱해두고 js파일을 나중에 클라이언트로 보냄 (이에 따라 js 상호작용은 js가 모두 다운된 이후에 가능)
장점
- 첫 페이지 로딩 시간( TTV, FCP )이 빠름
- 브라우저가 자바스크립트를 지원하지 않는 상태라도 컨텐츠 확인, 서비스 이용가능
- SEO 최적화가 매우 좋음 (검색엔진 크롤러가 페이지 내부 컨텐츠를 크롤링 가능)
- 코드를 클라이언트측으로 보내지 않아도 되기 때문에 보안이 뛰어남
- CDN에 캐시가 되므로 글로벌 서비스에도 데이터 지연을 최소화 해서 이용 가능
단점
- 빌드할때 렌더링이 됨으로, 데이터가 정적임
- 데이터가 클라이언트의 요청에 따라 즉시 반응해야 할 경우 적합하지 않음
- 사용자별 각각 다른 정보 제공이 어려움
Incremental Static Regeneration ( ISR )
특징
- App router의 안정화 버전 13.4 이후 사용되지 않음
렌더링하는 주체가 서버
SSG와 동일한 원리이지만, 정해진 주기에 따라 페이지가 새로운 데이터로 렌더링
최신 데이터를 주기적으로 업데이트 할 수 있는 이점이 있음
장점
SSG의 장점을 모두 공유
거기에 더해 데이터가 주기적으로 업데이트 될 수 있음
단점
SSG의 단점을 대부분 공유
SSG만큼 데이터가 정적이지는 않지만 여전히 실시간 데이터 적용은 어려움
Server Side Rendering ( SSR ) -> Dynamic Rendering
특징
- 렌더링하는 주체가 서버
- 클라이언트가 요청을 할때마다 매번 다시 렌더링
- 서버의 사양에 따라서 서비스의 속도가 좌우되는 경향이 있음
- 서버의 부하가 비교적 높음
장점
- SSG, ISR의 장점 대부분 공유
- 실시간으로 데이터를 사용할 수 있음
- 사용자별 필요한 데이터를 제공 가능
단점
- SSG, ISR에 비하여 비교적 느릴 수 있음
- 서버에 과부하가 걸릴 수 있음 ( Server Overhead )
- CDN에 캐시가 되지 않아 글로벌 서비스에 비교적 취약함
결론
어떤 기술이든 발전한다. 특히 프레임워크의 경우 배우고 정리하고 기록하여도 언제나 버려지는 부분, 더 이상 사용하지 않는 용도폐기되는 메소드와 기술이 그렇다.
어떤 시니어 개발자분께서는 과거의 기술을 잘 알고 있는 개발자가 오히려 실무에 방해가 된 적이 있다고 한다. 그 개발자분이 주니어였을때는 개발을 잘하는 프로그래머는 '메모리를 잘 활용하는 프로그래머'였지만, 현재는 그런 레거시한 개발 방식이 전혀 효용이 없기에 하는 말씀이셨겠지.
그렇다면 나는 개발자로서 어떤 기술을 공부하고, 어떤 기술을 '활용'만 할것인지 결정해야한다.
누구의 말대로 JS 자체는 프론트에서 불변의 기술이 될 것이니, 인간 MDN이 되는게 답인지,
그렇지 않으면 여러 프레임워크를 얕고 깊게 배워두어 언제든 사용이 가능한 상태로 만들 것인지,
혹은 기초 CS지식을 탄탄하게 쌓는 것인지... 오늘도 주니어 프론트 개발자는 머리가 아프다.