발표
2주차 발표
장경은

Web Application Rendering 전략

SPA(Single Page Application) (2005)

  • SPA가 등장하기 전에는, a태그를 클릭하여 다른 페이지로 이동하면 해당 페이지의 HTML을 다시 불러와야 했음 (SSG)
  • SPA는 AJAX의 등장과 함께 등장한 것으로, 사용자가 하나의 페이지 안에서 머무르면서, 변경이 필요한 부분만 부분적으로 업데이트
  • Web Application이 더 많이 사용하게 된 계기 (개인적인 생각)

CSR과 SSR

CSR (Client Side Rendering)

  • 클라이언트인 브라우저가 렌더링을 처리하는 방식
    • HTML 문서에는 body 태그 안이 텅텅 비어있고, 서버에서 JS파일을 받아서 이를 채워주는 방식
  • 새로고침이 발생하지 않아 화면 전환이 매끄럽고 서버 트래픽을 감소시킨다는 장점
  • 첫화면에서 HTML, CSS, JS가 모두 다운로드 되므로 첫 페이지 로딩 시간이 길고, SEO에 SSR보다 불리하다는 단점

SSR (Server Side Rendering)

  • SSR은 서버에서 화면을 그려서 브라우저에 전달하는 방식
  • 첫 페이지 로딩 속도가 CSR에 비해 빠르고, SEO 측면에서 CSR보다 더 유리하다는 장점
  • 그러나 페이지 이동 시 속도가 CSR보다 느리고 서버에 더 많은 요청을 보내야 한다는 점이 단점

최근에는 Next.js와 같은 프레임워크를 사용하면 서버 컴포넌트와 클라이언트 컴포넌트를 함께 사용할 수 있어 SSR과 CSR의 장점을 모두 살릴 수 있다.

Pre-rendering (Next 13 이전)

Building Your Application: Rendering (opens in a new tab)

  • Next.js는 기본적으로 모든 페이지를 사전 렌더링(Pre-rendering)한다.
  • 따라서 미리 HTML 파일을 만들어두어 더 좋은 퍼포먼스를 제공하고, 검색엔진최적화(SEO)에 이점이 있다.
  • next.js는 두 가지 사전 렌더링 방법을 제공한다.
    • Static Site Generation(SSG)
    • Server Side Rendering(SSR)
  • 이 두 가지는 언제 HTML 파일을 생성하는지에 차이점이 있다.

Static Site Generation(SSG)

  • 정적 생성 방법으로, 프로젝트가 빌드하는 시점에 HTML 파일들이 생성된다.
  • 미리 빌드된 HTML을 사용자의 요청이 들어올 때마다 재사용한다.
  • 정적 생성된 페이지들은 CDN에 캐시가 되고, 퍼포먼스를 이유로 Next.js는 정적 생성을 권고한다.
  • 유저가 요청하기 전에 미리 페이지를 만들어놔도 된다면 SSG을 사용하면 된다.
  • 그러나 데이터가 계속 바뀌어야하는 페이지라면 SSR을 사용하면 된다.
  • getStaticProps / getStaticPaths
  • 예시) 약관 보기 페이지

Server Side Rendering(SSR)

  • HTML 파일이 매 요청마다 생성된다.
  • 따라서 항상 최신 상태를 유지한다.
  • getServerSideProps
  • 예시) 커뮤니티 게시판

Incremental Static Regeneration(ISR)

  • 일정 주기마다 데이터의 최신 여부를 검사해서 업데이트된 데이터로 다시 HTML을 생성한다.
  • 콘텐츠가 업데이트 되었을 때 이것이 반영되지 않는 SSG의 단점을 보완한 방식이다.
  • getStaticPropsrevalidate 속성을 추가하여 사용
  • 예시) 제품 상세 페이지

Client Side Rendering(CSR)

App Router에서의 렌더링 (13버전)

  • Server Component와 Client Component가 존재
스크린샷 2024-01-27 오후 8 17 46
  • Next.js의 SSR, SSG, ISR은 Fetch에 어떤 옵션을 주느냐에 따라 다르게 동작한다.
  • 기본적으로 fetch에 아무런 옵션을 주지 않으면 자동으로 무기한 캐시한다. (SSG, ‘force-cache’)
    • fetch('https://...')
  • fetch에 옵션으로 { cache: ‘no-store’ } 를 주면 SSR로 동작한다. (SSR, 동적 데이터)
    • fetch('https://...', { cache: 'no-store' })
  • 타임 인터벌에 따라 캐시된 데이터를 재검증하려면, fetch()에서 next.revalidate 옵션을 사용하여 리소스의 캐시 수명(초 단위)을 설정할 수 있다. (ISR)
    • Time-base revalidation과 On-demand revalidation이 존재
    • fetch('https://...', { next: { revalidate: 10 } })
    • On-demand revalidation
    export default async function Page() {
        const res = await fetch('https://...', { next: { tags: ['collection'] } });
        const data = await res.json();
        // ...
    }
  • 그러나 각 layout.tsx에서 dynamic 옵션을 설정하면 이 옵션을 완전히 동적이거나 완전히 정적으로 바꿀 수 있다.
export const dynamic = 'auto';
// 'auto' | 'force-dynamic' | 'error' | 'force-static'`