React

[Next.js] 페이지 렌 더링 CSR, SSG, ISR, SSR

연신내고독한늑대 2024. 7. 24. 20:00

1. CSR(Client Side Rendering)

- 서버에서 빈 HTML, 라이브러리, JavaScript 코드를 다운로드하고 클라이언트(브라우저) 측에서 렌더링

useEffect으로 api통신하는 것

- 장점

    - 한 번만 로딩되면 빠른 UX 제공 →  fetch를 사용해 부분적으로 렌더링 가능

    - 서버의 부하가 적음 → 서버는 API 요청을 처리하지만, 페이지 렌더링은 클라이언트에서 수행. 이로 인해 서버의 부담이 상대적으로 적음

- 단점 

    - 초기 페이지 로딩 시간이 길다

    - js활성화 필수

    - 서버와 통신해야 해서 보안에 취약함

    - CDN에 캐시되지 않음

- 단점의 해결책으로 나온것이 SSG, ISR

# 예시 코드
// pages/index.js
import { useEffect, useState } from 'react';
import axios from 'axios';

export default function Page() {
  const [data, setData] = useState(null);
  useEffect(() => {
    axios.get('http://localhost:8080/api/user')
    .then(response => setData(response.data))
    .catch(error => console.error(error));
  }, []);

  if (!data) return <div>Loading...</div>;

  return <div>{data.name}</div>;
}

 

2. SSG(Static Site Generation) 

- 빌드 시 서버에서 렌더링함 → CSR의 단점 보안

- getStaticProps를 사용해야 함

- 장점

    - 페이지 로딩 시간이 빠름

    - 자바스크립트 필요 없음

    - 보안이 좋음

    - CDN 캐시 가능

- 단점 

    - 데이터가 정적임

    - 사용자별 정보 제공의 어려움 → 모든사용자한테 정적인 데이터일 때 굉장히 유리함

    - 서버측 데이터가 바뀔 때마다 재빌드 해야함 → 완전 잘 바뀌지 않는 데이터가 있을 때 SSG 사용해야 함

- 단점의 해결책으로 나온것이 ISR

#예시코드
// pages/index.tsx
import { GetStaticProps } from 'next';
import { fetchUser } from '../lib/api';

export const getStaticProps: GetStaticProps = async () => {
  const data = await fetchUser();
  return {
    props: {
      data,
    },
  };
};

export default function Page({ data }) {
  return (
    <main>
      <h1>User Information</h1>
      <pre>{JSON.stringify(data, null, 2)}</pre>
    </main>
  );
}

3. ISR(Incremental Static Regeneration) 

- 서버측에서 주기적으로 랜더링함 → SSG의 단점 보안

- SSG와 동일한 원리이지만 정해진 주기에 따라 페이지를 다시 생성함

- 장점

    - SSG의 장점 + 데이터가 주기적으로 업데이트

- 단점 

    - 실시간 데이터가 아님

    - 사용자별 정보 제공이 어려움

- 단점의 해결책으로 나온것이 SSR

- SSG코드에 revalidate: 60 추가

#예시코드
// pages/index.tsx
import { GetStaticProps } from 'next';
import { fetchUser } from '../lib/api';

export const getStaticProps: GetStaticProps = async () => {
  const data = await fetchUser();
  return {
    props: {
      data,
    },
    revalidate: 60, // ISR 설정 (60초마다 페이지를 재생성)
  };
};

export default function Page({ data }) {
  return (
    <main>
      <h1>User Information</h1>
      <pre>{JSON.stringify(data, null, 2)}</pre>
    </main>
  );
}

4. SSR(Server Side Rendering) 

- 서버측에서 요청시 랜더링함

- getServerSideProps를 사용해야 함 → 여기 안에 정의 된 기능들이 해당 화면을 클라이언트가 새로고침 할 때마다 실행 됨

- CSR(UseEffect)보다 초기 로딩 속도가 빠름 → 위에서 설명했듯이 CSR은 html을 먼저 띄워두고 js 로딩해서 오래걸림

- 서버에서 데이터를 실시간 수정했을 때 클라이언트에서 실시간으로 보여지고 싶으면 ISR처럼 특정 시간마다 호출을 시켜줄 수 있음

- 정적인 html을 먼저 보여주고 그 뒤에 js를 다운받아 실행함   그래서 그 사이의 간격(TTI: Time to Interact)을 줄이는게 중요포인트

- 장점

    - SSG장점 + 실시간 데이터 사용자 + 사용자별 데이터

- 단점 

    - 비교적 느릴 수 있음

    - 서버의 과부하 걸릴 수 있음 → CSR와는 다르게 각 클라이언트 요청에 대해 서버가 페이지를 동적으로 생성해야 하므로, 서버에 부담이 큽니다.

    - CDN캐시가 안됨

#예시코드
// pages/index.js
import { GetServerSideProps } from 'next';
import axios from 'axios';

export const getServerSideProps: GetServerSideProps = async () => {
  const response = await axios.get('http://localhost:8080/api/user');
  return { props: { data: response.data } };
};

export default function Page({ data }) {
  return <div>{data.name}</div>;
}

 

# nextjs는 ISR, SSG, SSR/CSR(심지어 한 페이지에서도 가능), CSR을 혼합해서 사용가능 -> 성능좋게 만들기 위해서