Next CSR vs SSR vs SSG vs ISR

Ell!·2022년 6월 10일
1

next

목록 보기
3/7

Next의 등장 배경

기존의 웹페이지 구현은 html + css에 js로 동적인 움직임을 표현해주는 방식으로 구현되었다. 그러다 Ajax라는 기술을 통해 일부분에서만 data를 가져오고 표현해줄 수 있게 되었고, SPA라는 개념이 등장하게 되었다.

SPA는 url을 이동하여도 새로고침하지 않는 것이다. 앱처럼 작동한다고 해서 웹앱이라고도 부른다.

반명에 SSR은 페이지를 새로고침할 때마다 서버에서 새로 리소스를 받아 다시 랜더링해준다. 기존의 CSR 방식은 앱처럼 작동하여 부드러운 url 이동을 보여주었고, 사용자 경험이 높았지만 SEO의 문제, 너무 큰 bundle 파일로 인해 유저가 첫 화면을 보기까지 오래걸린다는 문제가 생겼다.

이를 해결하기 위해 Next는 CSR과 SSR의 장점을 합치는 접근을 선택했다.
첫 페이지는 서버 사이드 렌더링하고 그 뒤에 발생하는 라우팅은 클라이언트 사이드 렌더링으로 하여서, 첫페이지는 안에 요소가 채워진 index.html을 받고
그 이후에는 js 파일은 따로 load해서 클라이언트에서는 DOM을 그대로 그리기만 하면 된다. code splitting 하지 않은 기존의 하나의 번들 파일을 내려주는 CSR 방식 보다 사용자가 화면을 보는 타이밍도 빨라진다

Next에서 rendering 선택하기


Next js를 사용한다! 라고 하면 자연스레 SSR을 통한 SEO 최적화를 생각하기 마련이다. 하지만 Next는 SSR만 제공하지 않는다. 오히려 Link 를 이용하면 CSR처럼 작동하기도 한다. Next를 사용한 다는 것은 미리 생성된 html (pre-render)과 기존의 CSR을 섞어 써서 SEO 최적화를 목표로 한다고 표현하는 것이 더 정확할 것이다.

그렇다면 CSR, SSR, SSG, ISR을 비교해가며, 어떤 페이지에서는 어떤 방식으로 rendering해야하는 지를 알아보겠다.

Data Integrity

얼만큼 최신 데이터를 필요로 하는지

목록비고랜더링
High매번 새로운 data가 필요함. ex) 제품 가격 표시, 게시글의 댓글, social mediaCSR, SSR
Medium새로운 data가 필요하나, 종종 이전의 데이터가 있어도 괜찮을 때. ex) 블로그 글, 프로필 페이지ISR
Low거의 바뀌지 않는 페이지 ex) about pageSSG

SEO

목록비고랜더링
SEO Friendly쇼핑 페이지, social medial, 지식인 서비스SSR, SSG, ISR
SEO Not-friendly로그인 페이지, 등록 페이지CSR

Instant

목록rendering
즉시SSG, ISR
랜더링 이전에 load 필요SSR, CSR

랜더링비고
CSRrendering이 진행되는 동안 loading spinner를 보여줄 수 있음. JS bundle 크기에 따라 다른 성능을 보여줌
SSR서버에서 data를 index.html에 포함시켜서 보내주기 때문에 맨 처음에 latency가 존재
SSG빌드할 때 생성되고, 사용자에 가까운 CDN에 캐싱됨. 가장 빠름
ISR역시 빌드할 때 생성되나, 때로 최신 데이터가 아닐 수 있음

Build Time

목록비고랜더링
Fastonly one page (사용자의 요청에 따라 그때 그때)SSG, ISR
Slowevery single page (1000개의 물건이 있으면 모두 진행하면서)SSR, CSR

Next data fetching

위에서 언급하였듯이 Next는 맨 처음 페이지를 랜더링할 때에는 서버사이드 랜더링의 방식을 취하지만 그 이후 다른 페이지를 이동할 때에는 클라이언트 사이드 랜더링의 방식을 취한다.
https://nextjs.org/learn/basics/navigate-between-pages/client-side

페이지 로드 순서

  1. 해당 page에 맞는 html 문서 get
  2. _appgetInitialProps 실행
  3. 각 페이지 별로 fetching 함수 실행 (getServersideProps, getStaticProps)
  4. _documentgetInitialProps 실행

만약 _app 에서 getInitialProps를 실행해주면 Automatic Static Optimization이 일어나지 않는다. (아래에서 자세히 다루겠다.)

기본 구조

export async function getStaticProps(context) {
  return {
    props: {}, // will be passed to the page component as props
  }
}

자세한 내용은 잘 정리된 next 공식문서에서~

Automatic static optimization의 정체

Next는 페이지에 getInitalProps (data fetching) 함수가 없으면 static page라고 판단한다.

next 공식 문서에 _app 에서 getInitialProps 를 사용하면 static optimization을 할 수 없다고 하는데, 바로 이런 data fetching 함수가 없는 페이지들을 미리 static html로 만드는 작업을 해줄 수 없다는 것이다.

next build 커맨드를 입력하면, static page들은 html을 만들어내고, 그렇지 않은 page들은 js 파일을 만들어낸다.

따라서 _app 에서 getInitialProps 를 사용하면 각 page는 getServersideProps getStaticProps 를 선택해서 사용해야 한다.

또한 _app 에서 getInitialProps 를 실행할 때, 각 페이지의 pageProps를 받아오므로, _app 에서 getInitialProps 을 custom 해주어야 한다.

MyApp.getInitialProps = async ({ Component, ctx }: AppContext) => {
  let pageProps = {}
  if (Component.getInitialProps) {
    pageProps = await Component.getInitialProps(ctx)
  }

  const theme = await fetchTheme(ctx.req?.headers.referer)

  pageProps = { ...pageProps, theme }

  return { pageProps }
}

export default MyApp

참고

https://iancoding.tistory.com/173

https://theodorusclarence.com/blog/nextjs-fetch-usecase

https://yoon990.tistory.com/59

https://simsimjae.medium.com/next-js-automatic-static-optimization-b56ba8febea8

https://velog.io/@chaerin00/Next.js-app.tsx에서-getInitialProps-커스텀하기

profile
더 나은 서비스를 고민하는 프론트엔드 개발자.

0개의 댓글