Next로 바라보는 CSR, SSR, SSG

user profile img

신현호

Web
Next.js
Post Thumbnail

목차

    서론

    블로그 프로젝트를 지속적으로 디벨롭해나가며, 제게 부족하던 useEffect, useMemo와 같은 react hooks를 조금 더 사용해나가며 리팩토링을 하고자 했는데,
    문득 next에서는 서버 컴포넌트에서 react hooks를 사용할 수 없던게 생각났습니다.

    서버컴포넌트여도 useMemo나 useEffect 와 같은 hook들을 쓰면 도움되는거 아닌가 하는 생각이 들어 CSR, SSR 그리고 더 나아가 SSR에 대해서도 한번 찾아보았고, 해당 물음에 대해서 답을 찾을 수 있었습니다.

    근본적으로 CSR과 SSR에 대해 이해가 부족해서 생긴 문제였습니다 :) 그래서! 오늘 포스팅은 제가 해당 파트에 대해서 공부한 내용에 대해서 정리해보려고 합니다.

    CSR, SSR, 그리고 SSG

    CSR (Client Side Rendering)

    CSR, 클라이언트 사이드 렌더링이라고 부르는 이 방법은 일반적으로 SPA (Single Page Application)에서 사용합니다.
    이를 사용하는 라이브러리 / 프레임워크에는 Vue, React, Angular 등이 있겠습니다.

    클라이언트 사이드 렌더링에서는 서버에서 데이터를 받아오고 브라우저가 해당 데이터를 통해 렌더링을 처리합니다.
    요약하자면, 브라우저가 렌더링의 주체가 된다고 볼 수 있습니다.

    이러한 특징때문에 CSR에서는 다음과 같은 장점을 가집니다.

    1. 네이티브 앱과 같은 빠른 인터렉션

      • 인터렉션이 발생하면 페이지 전체를 요청하는 것이 아닌, 변화된 부분만 리렌더링을 진행하기때문에 SSR보다 더 빠르게 인터렉션이 가능합니다.
      • 새로고침이 발생하지 않습니다.
    2. lazy-loading을 지원합니다

      • lazy-loading은 페이지 로딩 시 우선순위가 떨어지는 리소스들의 로딩을 늦추는 기술입니다.

    하지만, 해당 특징들로 인해서 다음과 같은 단점 또한 가집니다.

    1. 초기 페이지 로딩 속도가 SSR에 비해서 느립니다.

      • 필요한 데이터만 받는 것이 아닌, 전체 페이지에 대한 데이터를 받아오기 때문에 SSR보다 렌더링 속도가 느립니다.
    2. SEO (Search Engine Optimization) 능력이 떨어집니다.

      • 검색 포털(Google, Naver, ...etc)들은 index.html을 분석하여 검색력을 높여주는데 CSR의 경우에는 요청이 전달되기 전까지 body가 비어있어서 SEO가 효율적으로 동작하지 않습니다.
      • 추가적인 설정이 필요합니다. (react-helmet, react-snap, ...etc)

    SSR (Server Side Rendering)

    SSR, 서버 사이드 렌더링이라고 부르는 이 방법은 브라우저가 서버에 데이터를 요청한 결과를 렌더링 하는 방법입니다.
    서버 사이드 렌더링에서는 CSS까지 적용된 HTML과 JS 코드를 브라우저의 요청에 따른 응답으로 반환합니다.
    CSR과는 반대로 서버가 렌더링의 주체가 되는 렌더링 방법입니다.

    이를 사용하는 라이브러리 / 프레임워크에는 Gatsby, Astro, Next 등이 있겠네요. 사실 SSR 자체는 꽤 오래된 기술이라 저 외에도 JSP, PHP 등도 있습니다

    해당 특징으로 인해 장점은 다음과 같습니다.

    1. 페이지 로딩속도가 CSR에 비해서 더 빠릅니다.

      • 해당 페이지에 대한 문서만 브라우저에 전달하기때문에 CSR에 비해서 더 빠릅니다.
    2. SEO에 더 적합합니다.

      • 서버에서 html, js를 만들고 렌더링까지 모두 진행해서 client에게 넘기기 때문에 CSR과는 달리 body에 content가 있어 SEO에 적합합니다.

    다만 그렇기때문에 단점도 존재합니다.

    1. 필요한 부분만 리렌더링 하는게 아닌, 완전히 새로 렌더링합니다.

    2. 서버 과부하가 발생할 수 있습니다.

    3. TTV(Time to View)와 TTI(Time to Interact)간의 간극이 있습니다.

      • 뷰 자체는 서버에서 완성되지만, 클라이언트 측에서 자바스크립트 코드를 다운로드받아 생성된 HTML과 연결될 때 까지 인터렉션이 동작하지 않습니다.

    SSG (Static Site Generation)

    SSG는 서버에서 HTML을 보여준다는 점에서는 SSR과 유사하지만, 만들어주는 타이밍의 차이가 있습니다.
    SSR은 브라우저에서 요청 시 즉시 HTML을 만들어 응답하지만, SSG의 경우에는 페이지들을 모두 만들어 놓은 다음 해당 페이지의 요청이 들어오면 반환합니다.

    따라서 SSR은 데이터가 자주 바뀌어서 갱신이 잦은 프로젝트에 적합하고, SSG의 경우에는 갱신이 자주 되지 않아 캐싱이 필요한 프로젝트에 적합합니다.

    Server Component에서 React hook을 쓸 수 없는 이유

    Next13 버전에 들어오면서부터 서버 컴포넌트 / 클라이언트 컴포넌트 개념이 생겼습니다.
    이를 이해하기는 어렵지 않습니다. 말 그대로 서버 컴포넌트는 서버에서 렌더링되고 클라이언트 컴포넌트는 클라이언트에서 렌더링되기 때문입니다.

    Next 공식 문서에 따르면 서버 컴포넌트와 클라이언트 컴포넌트를 어떤 경우에 사용해야하는지 알려주고 있습니다.

    Next component

    여기에서 useEffect와 useState와 같은 hook들은 서버 컴포넌트에서는 사용할 수 없습니다.
    사용하지 말라는건 그렇다 치고, 왜 사용할 수 없는지에 대해서 궁금하지 않나요?

    그 이유는 바로 서버 컴포넌트의 특징에 있습니다.

    우리는 useMemo와 같은 Hook들을 이전의 값들을 캐싱하여 불필요한 리렌더링들을 방지하기 위해서 사용합니다.
    하지만 서버 컴포넌트는 서버에서 렌더링 된 후 리렌더링이 진행되지 않기때문에 서버측에서는 사용이 제한적이거나 의미가 없기때문에 사용하지 않는 것 입니다.

    Next에서 서버 컴포넌트에서 react hooks를 사용하지 못하게 한건 위와 같은 이유로 추측됩니다 :)

    끝으로

    저는 이것도 모르고 열심히 서버 컴포넌트에 useMemo를 활용하여 리팩토링을 진행하고 있었는데, SSR과 CSR에 대해서 차근차근 공부를 해보다보니 근본적으로 서버 컴포넌트에서는 이러한 최적화 기술이 필요가 없음을 깨닫을 수 있었습니다.
    덕분에 어렴풋이 알고있던 CSR, SSR, SSG에 대한 개념도 다시금 확립할 수 있었던 좋은 시간이었습니다 :)

    참고

    Profile Image

    신현호

    Frontend Developer

    프론트엔드 개발자를 꿈꾸고 있는 대학생입니다. 끊임없이 배우고 성장하는 개발자가 되기 위해 노력하고 있습니다.