React는 기본적으로 CSR(Client-Side-Rendering)로 처음에 빈 HTML을 보여주다가 브라우저에 접근 했을 시 Client에서 필요한 js를 다운 받아 보여준다.
Next에선 모든 페이지를 미리 렌더링(pre-rendering) 한다. Next 가 모든 일을 Client에서 처리하는 것이 아니라, 각 페이지의 HTML을 미리 생성한다.(서버단에서 DOM 요소를 빌드하여 HTML 미리 렌더링)
여기서 문제!
위와 같은 문제를 해결하기 위해 Hydration
이 등장한다.
Hydrate : Next 에서 생성된 각각의 HTML은 최소한의 JS코드와 함께 생성되고(ReactDom.Hydrate), 그 JS 코드는 페이지가 완전히 인터렉티브 할 수 있게 실행된다. 이러한 과정을 hydration 이라고 한다.
쉽게 말하면,
이러한 과정을 Hydration
이라고 한다.
Not Pre-rendering(React App)
Pre-rendering(Next.js)
사용자는 SSR을 통해 UI를 미리 보고, Hydration을 통해 페이지 조작이 가능해지는 것이다.
Pre-rendering에는 Static Generation(SSG), ISR과 Server side rendering(SSR)이 있다. 둘의 차이는 HTML을 생성하는 시기
에 있다.
Static Generation : 정적 생성
SSG는 빌드 타임에 HTML을 생성한다. (next build 명령어 입력 시)
SSG로 개발되는 페이지는 데이터에 의존하지 않는(Data fetching 하지 않는) 페이지들이 해당한다. 만약 해당 페이지에 대해 요청이 있으면 페이지를 재 로드하는 것이 아니라 이미 생성된 페이지를 반환하는 형태로 동작한다.
마이페이지, 소개페이지 같이 정적 생성된 정보를 각 요청에 동일한 정보로 반환하는 경우에 사용
Next에서 SSG 사용하기 위해 getStaticProps 메소드 사용
getStaticProps는 빌드 시 데이터를 패치하는 함수
getStaticProps 는 빌드 시 딱 한번만 호출 되며, 정적파일(static file)로 빌드 된다.
데이터가 자주 변경되지 않는 페이지에 적합하다.
export async function getStaticProps() {
// 빌드 시간에 데이터를 가져오는 비동기 작업을 수행합니다.
const data = await fetchData();
// 데이터를 페이지 컴포넌트의 props로 반환합니다.
return {
props: {
data,
},
};
}
getStaticProps에서 동적 라우팅이 필요할 때 적용하는 함수
export async function getStaticPaths() {
// 동적 경로를 빌드 시간에 생성합니다.
const paths = await generatePaths();
return {
paths,
fallback: false, // true로 설정하면 미리 정의하지 않은 경로로 요청 시 404 페이지가 아니라 빈 페이지를 반환할 수 있습니다.
};
}
SSR은 유저가 페이지를 요청할 때마다 HTML 문서를 생성해서 반환한다. 이러한 특징이 사용되는 경우는 항상 최신상태를 유지해야 되는 웹 페이지, 게시판, 분석 차트 등 사용자의 요청마다 동적으로 페이지를 생성하여 다른 내용을 보여주는 경우에 사용된다.
특징
Next.js는 pre-rendering 중 getServerSideProps 함수를 발견하면
컴포넌트 함수 호출 전에 getServerSideProps를 먼저 호출한다.
export async function getServerSideProps(context) {
// 데이터를 가져오는 비동기 함수
return {
props: {
// 데이터 객체
// ...
}
}
}
동적인 데이터가 필요한 경우 : 사용자의 로그인 상태, 쇼핑 데이터 같은 페이지가 렌더링 될 때 바뀌는 데이터가 있는 경우
SEO가 필요한 경우
SSG에 포함되는 개념이며 SSG와의 차이는 설정한 시간마다 페이지를 새로 렌더링 한다는 점이 있다.
SSG는 빌드 시에 페이지를 생성하기 때문에 데이터가 변경되면 다시 빌드를 해야하지만, ISR
은 일정 시간마다 특정 페이지만 다시 빌드하여 페이지를 업데이트
한다.
export const getStaticProps = async ({ params }) => {
const id = params.id;
const res = await axios.get(`https://url/${id}`);
return {
props: {
list: res.data,
},
revalidate: 20,
};
};
const Detail = ({ list }) => {
<ul>
{list.map((item) => (
<li key={item.id}>{item.title}</li>
))}
</ul>;
};
블로그와 같이 컨텐츠가 동적이지만 자주 변경되지 않는 사이트인 경우
ISR을 사용하는 것이 좋다.
SSG와 getStaticProps 사용 방법은 같지만 revalidate에 명시된 숫자(초)마다 페이지가 새로 렌더링 되는 차이가 있다.
CSR
SSG
ISR
SSR