CSR vs SSR vs SSG vs ISR

Next.js 14

2023년 10월 26일 Next.js 버전 14가 발표되었다.

중요한 업데이트를 크게 다음 3가지로 분류하였다.

1. Turbopack 관련

2. Server Actions 안정화

3. Partial Pre-rendering 

 

이 중에 Partial Pre-rendering 관련해서 공식문서를 인용하면

(https://nextjs.org/blog/next-14#partial-prerendering-preview)

Partial Prerendering builds on a decade of research and development into server-side rendering (SSR), static-site generation (SSG), and incremental static revalidation (ISR).

 

번역하자면 Partial Pre-rendering은 10년간의 SSR, SSG, ISR의 연구 개발의 결과라고 한다.

그렇기에 이 개념에 대해서 우선 이해할 필요가 있다.

 

CSR (Client-side rendering)

공식적인 설명은 많으니 여기서는 간단하게 개념만 쓰려고 한다.

기본적으로 browser에서 url 주소를 입력하고 엔터를 치면

해당 서버에 요청(request)을 보내는 행위이다.

그러면 서버는 index.html 파일에

<div id="root"></div>

 

라는 HTML 요소 하나와 여러 CSS와 JS(javascript)를 브라우저에 보낸다.

그래서 이것이 한 때 유행했던 SPA(single-page application)의 이름의 유래가 되었다.

브라우저(Client)는 이를 받아서 렌더링한다.

다른 uri로 옮겨간다해도 html 파일을 추가로 server에서 받아오지 않아도 되므로 '한 번 초기 로딩된 후'에는 속도가 빠르다.

Virtual DOM과 DOM을 이용해 렌더링 된다.

이런 CSR을 잘 구현해주는 React라는 library가 있고, Vue와 Angular 같은 framework이 있다.

 

 

장점:

  Input form처럼 고객과 interaction에 집중된 사이트라던지, 실시간으로 변하는 초시계를 랜더링하거나 할 때는 CSR이 가장 유리하다. NavBar(상단 메뉴바)를 클릭했을 때 main section이 빠르게 랜더링한다는 이점이 있다.

단점: 

  1. SEO에 취약. 최근 search engine은 이런 CSR 방식도 어느 정도 지원한다고 하지만 한계가 있다.

  2. 초기 페이지 로딩 속도가 느림.

  단점은 딱 이 두 가지이지만 이 두 가지 단점이 홈페이지의 수익성에 직접적으로 영향이 있어서 문제다. 

 

  이에 대해서는 다음 두 개 글에서 다루어 보겠다.

 

SSR (Server-side rendering)

Server-side rendering은 client(browser)에 보내기 전 server에서 HTML content가 생성되는 것을 말한다.

플래티어에는 백엔드 개발자가 주를 이루고 있기 때문에 SSR의 개념은 대부분 익숙할 것 같다.

브라우저에서 javascript를 parse하는 시간이 절약되기 때문에 '초기 로딩 속도'가 훨씬 빠르다.

Client(browser)가 페이지를 요청하면 server가 필요한 data를 fetch하고 HTML content를 생성해낸다.

장점:

  초기 로딩가 빠르기 때문에 메인페이지의 content-heavy 사이트에서 이점이 있고 

  SEO 최적화가 가능하다.

  백엔드+프론트엔드 전부 코딩 가능. React에 익숙하던 사람은 Next.js, Vue에 익숙하던 사람은 Nuxt.js를 쓰면 된다.

단점:

  플래티어의 NFT 시연 사이트는 순수 Java Spring Boot와 thymeleaf로 만들어진 페이지다. 그래서 Navbar의 메뉴를 클릭하면 전체 페이지가 재로딩되면서 깜빡 거린다. UX측면에서 좋지 않다.

  websocket이나 webRTC를 만들 때는 따로 node 서버를 독립적으로 만들어야한다.

 

 

대강 개념은 이렇지만, 조금 더 엄밀히 얘기하자면, 예를들어 onClick()과 같은 Javascript, 즉 interactive component를 위한 Javascript는 browser가 user와 interaction하는데 사용해야하기 때문에 javascript를 일부분 보낸다. 그래서 client가 최종적으로 완성된 페이지를 렌더링한다. 이제 Hydration error를 이해할 수 있다.

Hydration error

이미 server에서 받아서 그대로 client에서 이미 초기 렌더링이 끝난 HTML content와, interactivity와 behavior를 추가로 붙일 때 많은 차이가 나면 이는 hydration error로 이어진다.

다시 말하면 서버에서 생성된 content와, client에서 렌더링된 content가 다르면 생기는 에러다.

그러나 이 주제는 나중에 더 자세히 살펴보기로 한다.

 

SSG (Static Site Generation)

SSG는 build process에서 HTML file을 pre-rendering하는 방식이다.

가장 유명한 framework는 아마도 Gatsby 프레임워크다.

블로그와 같이 한 번 쓴 글은 잘 변하지도 않으니 빌드할 때 미리 만들어놓는 것이 유리하다.

이러면 서버에서도 파싱을 하지 않으니 로딩 속도가 엄청 빨라진다.

 

 

ISR (Incremental Static Regeneration)

ISR은 SSR과 SSG를 합친 방식이다.

Static page를 빌드 타임에 pre-render하고 주기적으로 (예: 60초에 한 번씩) 특정 page만 재생성하는 방식이다.

이를 revalidation이라고 부른다.

E-commerce에서는 상품의 가격이 실시간으로 바뀌지도 않지만, 어느 시점에 할인 가격을 제시하고 싶을 때 ISR의 이점을 살릴 수 있다.

플래티어의 X2BEE 백엔드에서 상품을 등록할 때도 등록 시점부터 0.1초만에 store front에 노출될 필요가 없다면 ISR 방식이 store front의 속도에 좀 더 이점을 줄 수 있다.

Next.js 공식문서를 보면 getStaticProps()와 getStaticPaths()와 같은 methods로 구현할 수 있다.

 

다음 코드는 역시나 Next.js Conf 2023에서 BigCommerce가 자신들의 코드라고 공개한 부분이다.

await client.addCartLineItem(cartId, {
  lineItems: [
    {
      productEntityId,
      quantity: 1,
    },
  ]
});

revalidateTag('cart');

return;

 

장바구니에 아이템을 추가하는 메소드를 짜고, revalidate을 사용해 UI update하는 것으로 볼 수 있다.

 

DSG (Deferred Site Generation)

SSG가 서버에도 클라이언트에도 부담이 줄지만, 단점이라면 크기에 비례하는 build timebundle size다.

Gatsby framework에서도 ISR 비슷한 방식을 쓰는데 Gatsby는 DSG(Deferred(연기된) Site Generation)이라는 단어를 쓴다.

DSG는 예를들어 1,000개의 페이지가 있으면 중요한 100개만 빌드타임에 빌드하고, 나머지는 client 요청이 있을 때 server에서 HTML content를 생성한다. 즉 이것도 SSG와 SSR를 합친 방식이다. 

ISR과 DSG의 또 하나의 차이점은 ISR은 server-side API call을 하지만 DSG는 data를 pull 받을 때 cached-at-build-time data layer를 사용한다고 한다.

 

결론

위의 장단점을 요약하면 다음과 같다. 

중요한 것은 Next.js는 이 4가지 기능을 전부 제공해주고 있다는 점이다. (물론 Nuxt.js도 다 제공한다.)

 

Frontend Frameworks

현재 Svelte가 무서운 속도로 사용빈도가 늘어나고 있지만 아직까지 Frontend 3대장은 다음과 같다.

엄밀히 말하면

최근 React18 버전부터 RSC(React Server Component)의 등장으로 React도 온전한 CSR이 아니고,

Next.js에서 'use client'를 사용해도 순수 CSR 렌더링이 아닌 버전 13.3 이전의 pages Router방식의 hydration SSR 방식으로 렌더링을 한다.

그러나 처음 입문한다면 우선 CSR과 SSR의 개념부터 알아야한다.

  • 네이버 블로그 공유
  • 네이버 밴드 공유
  • 페이스북 공유