Next.js에서의 SSR과 SSG
데이터 페칭 방식
Next.js에서 서버로부터 데이터 페칭하는 방식에는 대표적으로 세가지가 있다.
각 방식들을 통해, 서버로부터 데이터를 어떻게 받고 렌더링할지를 개발자가 선택해 활용할 수 있다.
Next.js에서는 아래 사진과 같은 api를 통해 SSR과 SSG를 구현할 수 있다.
차례대로 getStaticProps
, getStaticPaths
, getServersideProps
다.
getStaticProps
SSG 방식이라고 생각하면 된다.
빌드 단계에서 정적 페이지(html)를 미리 생성하고, 서버로부터 미리 그려진 해당 페이지를 받아와 화면에 표시해준다. SSG에 기반을 둔 방식이기에, 데이터 변화가 없이 고정적으로 보여줘야 하는 화면 구성에 있어 활용하는 것이 좋다. 그리고 단순 GET
요청으로 페이지만 불러오는 것이기 때문에 후술할 getServersideProps
보다 속도 측면에서는 훨씬 우월하다.
따라서, 아래와 같은 경우에 getStaticProps
의 사용을 고려할 수 있다.
- 데이터의 동적 변화가 없는 정적 페이지일 때 (ex. 고정된 대분류 카테고리 화면, 회사 규정, 카테고리 등등)
- SEO가 필요한 컴포넌트일 때
예시 코드
1 | // { posts }는 빌드타임에 getStaticProps에 의해 채워진다. |
getStaticPaths
getStaticProps
와 “함께” 사용해줘야 하는 api다.
getStaticProps
는 상술했듯, 미리 html파일을 빌드타임에 생성해두는 방식이다. 하지만 Next.js의 특성상 동적라우팅을 사용하는 경우가 잦다. ex) items/[id].tsx
즉, 동적 라우팅을 사용할 때 어떤 params
마다 SSG방식을 사용할지 미리 옵션을 지정해주는 것이라고 생각하면 된다.
1 | export async function getStaticPaths() { |
위의 예시에서 만약 items/[1 ~ 10].tsx
까지 존재한다고 한다면, 1 ~ 10 까지의 params 중 어디까지 SSG방식을 사용할 것인지 미리 정해줄 수 있는 것이다.
그렇다면 위에서 사용한
fallback
프로퍼티는 무엇을 의미하는걸까?
그것은 바로 “등록되지 않은 params에 대해서는 어떻게 처리할 것인가?”에 대한 핸들링을 위한 프로퍼티다. 나중에 params
에 id
11이 추가됐다고 가정했을 때, 해당 id 11은 아직 getStaticPaths에 등록되지 않았기에 이를 어떻게 처리할지 우리 next.js는 모른다. 이 때 fallback
을 true
로 설정하면 새로 추가되는 등록되지 않은 params도 빌드 시에 static으로 생성된다. 반대로, false로 설정하면 등록되지 않은 params에 대해선 404 페이지로 연결된다.
fallback: true
일 때의 플로우를 조금 더 자세히 작성해보자면 아래와 같다.
fallback
페이지를 사용자에게 임시로 보여준다.if (router.isFallback) return <Loading/>
- 서버에서 SSG를 수행한다. (html 생성)
- 생성이 완료되면 해당 페이지가 렌더링 된다.
- 이후부터는 해당 params로 접속할 때 SSG가 바로 적용된다.
마지막으로 fallback에서의
blocking
은 무엇을 의미할까?
true
일 때는 fallback페이지를 보여준 뒤 SSG 후 페이지를 렌더링 해줬다. 하지만 blocking
으로 설정된 경우에는 위의 과정을 거치지 않고 서버사이드 렌더링 방식을 통해 static 페이지를 보여주며 → 이후부터는 해당 static 페이지를 동일한 params에 대해 제공해준다. 즉, fallback페이지와 같은 특정 로딩 등의 화면이 존재하지 않는 방식이라고 생각하면 된다.
getServersideProps
getServersideProps
= SSR방식이라고 생각하면 된다.
이는 빌드타임이 아닌 런타임에 데이터를 페칭한다는 특징을 갖는다.
SSR방식이기 때문에 당연히 데이터가 동적으로 자주 변하는 컴포넌트에서 활용하는 것이 좋다. 데이터의 요청이 잦고 다양한 경우에는 그에 따라 렌더링 되어야 하는 컴포넌트와 UI도 다이나믹할 것이기 때문이다.
좀 더 자세히 말하자면, 특정 화면을 렌더링하는 데 있어 특정 데이터의 페칭이 필요한 경우에 getServersideProps
의 사용을 고려해볼 수 있는 것이다.
대표적인 예로, 로그인을 했을 때의 화면과 안했을 때의 화면이 다른 경우, 위치정보를 받아 현재 위치에 기반한 지도나 정보들을 표시해줘야 하는 경우를 들 수 있다.
따라서, 매 요청마다 서버로부터 데이터를 미리 페칭하여 서버사이드에서 해당 데이터를 활용해 특정 부분(컴포넌트)이나 페이지를 pre-render하여 클라이언트에 보내준다고 이해하면 된다.
예시 코드
1 | function Home({ user }) { |
캐싱
getServersideProps를 통해 데이터에 대한 캐싱 기능 또한 활용할 수 있다.
1 | // 이 값은 10초동안 fresh한 상태로 여겨진다. (s-maxage=10) |
정리
SSG와 SSR을 조금 비유적으로 표현해보자면, SSG방식은 미리 만들어놓은 햄버거 밀키트를 판매하는 것이고, SSR 방식은 수제버거집에서 고객들이 다양한 요구사항과 메뉴를 주문할 때, 그에 맞는 햄버거를 만들어 판매하는 방식이라고 이해해도 될 것 같다😂.
참조한 자료
Next.js에서의 SSR과 SSG