일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- npm install
- ES6
- ios
- Android
- shortcut
- ReactNative
- styled-components
- GitLab
- React Native
- nextJS
- HTML
- REACT
- vscode
- DevOps
- npm
- git
- rn
- JavaScript
- styling
- currying
- commit
- Xcode
- github
- Branch
- Docker
- viewcontroller
- xtring.log
- react-native
- js
- Swift
- Today
- Total
xtring.dev
[Next.js] Next.js 공식문서 파헤치기(2) - 기본개념 "Pages, Pre-Rendering 방식(SSG/SSR)" 본문
[Next.js] Next.js 공식문서 파헤치기(2) - 기본개념 "Pages, Pre-Rendering 방식(SSG/SSR)"
xtring 2021. 7. 29. 19:30
Next.js에는 몇가지 강력한 특징이 있습니다.(아래) 이번 아티클에서는 SSG와 SSR에 대한 내용을 설명드리겠습니다🤓
Next.js의 Pages
Next.js에서 page는 pages
디렉터리의 .js
, .jsx
, .ts
, .tsx
파일로부터 export된 React Component입니다. 각 페이지는 그들의 파일 이름을 기반으로 route됩니다.
예를 들어, 만약 pages/about.js
파일을 생성한다면 /page
로 쉽게 접근가능합니다.
function About() {
return <div>About</div>;
}
export default About;
이렇게 About은 하나의 페이지로서 사용됩니다.
Pre-rendering; 사전 렌더링
기본적으로, Next.js는 모든 페이지를 pre-rendering합니다. 이는 Next.js가 Client-side의 JavaScript에 의해 실행하는 것 대신에 사전에 각 페이지의 HTML을 생성하는 것을 의미합니다.(pre-render) 그리고 이러한 pre-rendering 방식은 더 나은 성능과 SEO을 가능하게 합니다.
각각 생성된 HTML은 그 페이지를 위한 최소한의 JavaScript code로만 이루어집니다. 브라우저에서 하나의 페이지가 로드될 때 그 페이지의 JavaScript code가 실행(로드)되고 페이지를 반응(interacitve)성 있게 만듭니다.(이러한 과정을 hydration(수분 공급)이라고 합니다.)
Pre-rendering의 두가지 방식
Next.js는 Static Generation
과 Server-side Rendering
이라는 두가지 방식의 pre-rendering 방식을 가지고 있습니다. 이 둘의 가장 큰 차이점으로 페이지의 HTML이 생성되는 방식에서 차이가 있습니다.(지금은 잘 이해가 되지 않을 수 있지만 이 아티클을 끝까지 보신다면 이해할 수 있습니다!)
Static Generation
: HTML은 build-time에 생성되며 모든 요청에서 미리 생성된 HTML을 재사용(Next.js's recommand)Server-side Rendering
: HTML은 각각의 요청마다 생성. 즉, 재사용은 하지 않음
중요하게도, Next.js는 각 페이지에 당신이 사용하고자 하는 pre-rendering 방식을 선택할 수 있게 해줍니다. 또한 더 나아가 대부분의 페이지에서는 Static Generation
을 사용하고 다른 페이지에서는 Server-side Rendering
을 이용하여 "Hybrid"
Next.js 앱을 만들 수 있게 해줍니다.
Next.js에서는 성능상의 이유로 Server-side Rendering
방식보다 Static Generation
방식을 사용하는 것을 추천합니다. Static Generation
페이지는 성능 향상을 위한 추가 구성없이 CDN에서 캐싱을 합니다.(이를 통해 미리 생성해 놓은 HTML을 다시 재사용 할 수 있습니다.) 그러나 페이지에 최신의 데이터를 유지해야하는 경우 Server-side Rendering
이 유일한 선택일 수 있습니다. 또한 Next.js는 Client-side Rendering
방식도 지원합니다...! 이 방식은 페이지 일부를 클라이언트 측에서 JavaScript를 실행시킨다는 말입니다.
Static Generation
Static Generation
을 사용한다면, 페이지의 HTML은 build-time(빌드 시점)에 생성됩니다.즉, production에 페이지의 HTML은 'next build'가 실행되는 시점에 생성된다는 말입니다. 생성된 HTML은 각각의 모든 요청(request)에서 재사용될 것입니다. 그리고 CDN에 의해 캐싱될 수 있습니다.
생성되는 페이지에서 데이터를 포함하냐 안 하냐에 따라 Static Generation
을 사용할때 조금 다릅니다. 이유는 build-time에서 미리 HTML을 생성하기 때문이겠죠? 아래에서 외부 데이터를 가져오는 경우와 아닌경우를 살펴봅시다.
Static Generation without data
function About() {
return <div>About</div>
}
위 코드에서는 pre-render과 함께 데이터를 가져오지 않습니다. 이러한 경우 build-time에 page의 HTML생성합니다.
Static Generation with data
때때로 pre-rendering을 위해 외부 데이터를 가져와야하는 경우가 있습니다. 두 가지 시나리오가 있으며 하나 또는 둘 다 적용될 수 있습니다. 각각의 경우에 Next.js가 제공하는 다음 기능을 사용할 수 있습니다.
(1) 당신의 page contents가 외부 데이터에 의존하는 경우 ⇒ getStaticProps
(2) 당신의 page path가 외부 데이터에 의존하는 경우 ⇒ getStaticPaths
(일반적으로 getStaticProps
와 함께 사용)
시나리오 1) 페이지의 contents가 외부 데이터에 따라 다른 경우
당신의 blog page는 CMS(Content Management System)으로부터 blog post 리스트를 가져와야 한다.
// TODO: pre-render가 이루어지기 전에 API을 통해 post를 가져와야 한다.
function Blog({ posts}) {
return (
<ul>
{posts.map((post) => (
<li>{post.title}</li>
))}
</ul>
)
}
데이터를 가져와 pre-render하기 위해서, Next.js를 사용하면 해당 파일에서 getStaticProps
함수를 비동기 방식으로 export하여 사용합니다. 이 함수는 build-time 시 호출되며 pre-rendering 시 가져온 데이터를 page의 contents로 전달할 수 있습니다.
function Blog({ posts }) {
// Render posts...
}
// build-time 시 실행
export async function getStaticProps() {
const res = await fetch('https://.../posts');
const posts = await res.json();
return {
porps: {
posts,
}
}
}
export default Blog;
시나리오 2) 페이지의 경로가 외부 데이터에 따라 다른 경우
Next.js는 Dynamic Routing을 통해 페이지를 생성합니다. 예를 들어,pages/posts/[id].js
파일을 생성합니다. 'id' 기반의 단일 블로그 포스트를 보여주기 위해서posts/1
을 액세스할 때 id: 1인 블로그 포스트를 볼 수 있습니다.
id 값은 pre-rendering 시 외부 데이터에 따라 달라질 수 있습니다. 이것을 다루기 위해서 동적 페이지(pages/posts/[id].js
)로 부터 getStaticPaths
함수를 비동기 방식으로 사용합니다. 이 함수는 build-time에 실행되며 pre-rendering을 위해 원하는 path를 구체화합니다.
export async function getStaticPaths() {
const res = await fetch('https://.../posts');
const posts = await res.json();
const paths = posts.map((post) => ({
params: { id: post.id },
}));
// { fallback: false }는 다른 (예외 케이스의) 라우팅 시 404를 발생한다는 의미
return { paths, fallback: false }
}
그리고, pages/posts/[id].js
에서 getStaticProps
를 export 하게되면 id를 가진 게시물에 대한 데이터를 가져와 페이지를 pre-render하는데 사용할 수 있습니다.
function Post({ post }) {
// Render post...
}
export async function getStaticPaths() {
// ...
}
export async function getStaticProps({ params }) {
const res = await fetch(`https://.../posts/${params.id}`)
const post = await res.json()
return { props: { post } }
}
export default Post
언제 Static Generation을 사용해야 할까?
Next.js 공식 문서에서는 Static Generation(with or without data)을 사용하는 것을 가능한 권장합니다. 왜냐하면, build-time에 생성된 HTML을 CDN 캐시를 통해 제공하기 때문에 각 요청에 따라 Server-side rendering 하므로 더 빠른 성능을 보여줄 수 있기 때문입니다. 예를 들어 아래 페이지들에서 사용합니다.
- Marketing pages
- Blog posts
- E-commerce product listing
- Help and documentation
스스로에게 "사용자의 요청에 앞서 이 페이지를 pre-rendering해도 되는가?"를 물어보세요. 대답이 "예"라면 Static Generation
을 사용하면 됩니다.
반면, Static Generation은 사용자가 요청하는 데이터를 보여줘야하는 경우엔 적합하지 않습니다. 페이지에 따라 데이터가 자주 업데이트 되는 경우 매 순간 페이지의 contents가 변경될 수 있기 때문입니다. 아래의 경우를 살펴봅시다.
(1) Client-side Rendering과 함께 Static Generation을 사용하는 경우
페이지의 일부를 pre-rendering하지 않고 Client-side에서 JavaScript를 실행항여 contents를 채울 수 있습니다.
(2) Server-side Rendering을 하는 경우
페이지를 매번 서버에서 pre-rendering하면 CDN을 통한 캐싱이 의미가 없기 때문에 rendering 성능이 저하됩니다. 하지만 데이터와 contents는 항상 최신을 유지할 수 있습니다. 만약, 하나의 페이지에서 Server-side Rendering을 사용한다면, HTML 페이지는 매 순간 요청(request)에 의해서 생성된다는 말입니다.
Server-side Rendering(SSR, Dynamic Rendering)
만약 하나의 페이지에서 Server-side Rendering하게 되면, HTML 페이지는 모든 요청(request)에서 생성됩니다.
하나의 페이지를 Server-side Rendering
하기 위해서, getServerSideProps
함수를 비동기 처리하여 사용합니다. 이 함수는 모든 요청(request)에서 Server에 의해 실행됩니다.
예를 들어, 외부 API로 부터 자주 업데이트되는 데이터를 pre-rendering하기 위한 페이지가 필요하다면, 데이터를 가져오기 위한 getServerSideProps
함수를 작성할 수 있으며 아래 코드와 같이 페이지에 데이터를 전달할 수 있습니다.
function Page({ data }) {
// Render data...
}
export async function getServerSideProps() {
const res = await fetch(`https://.../data`);
const data = await res.json();
return { props: { data } };
}
export default Page;
위 코드를 보면 getServerSideProps
는 getStaticProps
와 비슷합니다. 그러나, getServerSideProps
는 build-time이 아닌 모든 요청(request) 마다 실행되는 차이점을 가집니다.
Ref.
https://nextjs.org/docs/basic-features/pages#scenario-1-your-page-content-depends-on-external-data
'Front-End > Next.js' 카테고리의 다른 글
[Next.js] Next.js 공식문서 파헤치기(1) - 시작하기 (0) | 2021.07.22 |
---|