hmk run dev
Next.js 정적 생성(Static Generation) - getStaticProps, getStaticPaths 본문
Next.js 정적 생성(Static Generation) - getStaticProps, getStaticPaths
hmk run dev 2022. 3. 1. 15:53Pre-rendering
- 기본적으로 모든 페이지 프리 렌더링
- 사전에 HTML 파일을 만든다는 의미
- 퍼포먼스 향상, SEO
next.js에서 자바스크립트를 껐을때 보여지는 화면을 관찰해보자!
끄는 방법 > F12 > F1 > Debugger > Disable Javascript
왼쪽이 끄기 전 오른쪽이 끈 후입니다.
메인페이지
상세페이지
서버사이드 렌더링으로 만든 상세 페이지는 CSS차이 정도 밖에 없는 것 같습니다 :)
> 서버에서 이미 데이터를 가져와 HTML로 만든다음에 내려줘서!
no Pre-render & Pre-render
no Pre-render - 아무것도 없다가 JS가 로드 된 이후에 화면을 그리기 시작함
Pre-render - 사전에 만들어진 HTML 메타데이터 포함 요소들이 나온다 이후 JS가 로드된 이후 JS 기능들이 작동을함
> Hydration 정적이 요소들에 생기를 불어넣는? 것을 의미함
Pre-render는 두 가지 방식으로 생성될 수 있는데
Static Generaion(정적생성), Server side Renderring(서버 사이드 렌더링)
차이점은 언제 html 파일을 만드냐 입니다.
Static Generaion(정적생성)
빌드 시 html 파일을 만듦
Server side Renderring(서버 사이드 렌더링)
요청 시 html 파일을 만듦
Next.js는 정적 생성을할지 SSR을 할지 페이지마다 개발자가 정할 수 있음!
Nextjs에선 아래 페이지들을 정적생성 할 것을 권고하고 있습니다.
- 마케팅 페이지
- 블로그 게시물
- 제품 목록
- 도움말, 문서
SSR 권고 페이지
- 항상 최신 상태가 필요한 페이지
- 관리자 페이지
- 분석 차트
그렇다면 기존 정적생선 변경 전 후 코드를 비교해보자
useEffect를 통해 서버와 통신하고 데이터를 가져와서 뿌려준다.
export default function Home() {
const [list, setList] = useState([]);
const [isLoading, setLoading] = useState(true);
const API_URL = process.env.NEXT_PUBLIC_API_URL;
function getData() {
Axios.get(API_URL).then((res) => {
console.log(res.data);
setLoading(false);
setList(res.data);
});
}
useEffect(() => {
getData();
}, []);
return (
<div>
<Head>
<title>HOME | hmk1022</title>
</Head>
{isLoading && (
<div style={{ padding: "300px 0" }}>
<Loader inline="centered">Loading...</Loader>
</div>
)}
{!isLoading && (
<>
<Header as="h3" style={{ paddingTop: 40 }}>
베스트 상품
</Header>
<Divider />
<ItemList list={list.slice(0, 9)} />
<Header as="h3" style={{ paddingTop: 40 }}>
신상품
</Header>
<Divider />
<ItemList list={list.slice(9)} />
</>
)}
</div>
);
}
getStaticProps를 통해 데이터를 받아와 props로 넘기고 화면에 뿌려준다!
export default function Home({ list }) {
return (
<div>
<Head>
<title>HOME | hmk1022</title>
</Head>
<>
<Header as="h3" style={{ paddingTop: 40 }}>
베스트 상품
</Header>
<Divider />
<ItemList list={list.slice(0, 9)} />
<Header as="h3" style={{ paddingTop: 40 }}>
신상품
</Header>
<Divider />
<ItemList list={list.slice(9)} />
</>
</div>
);
}
// 정적 생성
export async function getStaticProps(context) {
const apiUrl = process.env.apiUrl;
const res = await Axios.get(apiUrl);
const data = res.data;
return {
props: {
list: data,
name: process.env.name,
},
};
}
빈 화면을 그린후 api 호출을 통해 화면을 채우는것이 아닌
미리 만들어진 static 파일을 보여준다!
이상태로 build를 하고 build 파일 안을 보게되면
빌드 시점 만들어진 html 파일들이 엄청나게 긴 코드로 생성되어 있습니다..!
그렇다면 다이나믹 라우트를 사용하는 페이지는 정적으로 생성할 순 없을까??
갯수가 한정적이라면 가능합니다.
getStaticPath
정적 생성할 페이지를 한정적으로 만들었습니다.
const Post = ({ item, name }) => {
return (
<>
<Head>
<title>{item.name}</title>
<meta name="description" content={item.description}></meta>
</Head>
{name}환경입니다.
{item && <Item item={item} />}
</>
);
};
export default Post;
// 정적 생성
export async function getStaticPaths(context) {
return {
paths: [
{ param: { id: "740" } },
{ param: { id: "730" } },
{ param: { id: "729" } },
],
// true로 변경시
// 최초 접속시 props가 빈 상태면 이후에 백그라운드에서 정적으로 html 생성
// 두번째 접속 시 정적생성된 페이지 사용
// fallback: true,
fallback: false,
};
}
export async function getStaticProps(context) {
// context는 params나 요청 응답 쿼리 등이 담겨서 온다
const id = context.params.id;
const apiUrl = `http://makeup-api.herokuapp.com/api/v1/products/${id}.json`;
const res = await Axios.get(apiUrl);
const data = res.data;
return {
props: {
item: data,
name: process.env.name,
},
};
}
아래 세개의 상품상세보기는 정적생성으로 빌드시 만들어진 html 파일을 보여줍니다.
만들어진 파일을 보여주니까 클릭시 체감상 속도가 매우 빠릅니다.
물론 위 세개 상품말고 다른 상품 클릭시 404 페이지를 보여주겠죠..? ^^
getStaticPaths의 fallback
이 옵션을 true로 바꿔주면 미리 정적 생성한 상세 페이지 외에 다른 게시물을 클릭 시
흰 화면이 잠시 보여졌다가 상세페이지를 보여준다.
이는 nextjs가 클릭한 상품페이지를 정적페이지로 직접 생성해 주는 것으로
최초 클릭 시 생성을 한 번하고 다음 부턴 만들어진 페이지를 보여준다는 옵션입니다.
페이지가 많다면 쓸 수 있는 방법입니다.!
'React' 카테고리의 다른 글
리액트 성능 측정 & 개선하기 (feat. memo & React DevTools) (0) | 2024.04.20 |
---|---|
useMemo와 useCallback (0) | 2022.03.22 |
next.js의 SSR (0) | 2022.03.01 |
Next.js의 장점과 프로젝트 구조 (0) | 2022.03.01 |
async, await (0) | 2021.05.20 |