getServerSideProps(SSR)
getServerSideProps를 사용하면 getServerSideProps return값을 참조하는 각각의 페이지들이 pre-render된다.
export async function getServerSideProps(context) {
return {
props: {}, // will be passed to the page component as props
}
}
⚠️Caution
어떤 렌더링타입과도 관계없이 모든 props는 페이지 컴포넌트로 전달되며 초기에 Next에 의해 빌드된 HTML 즉, 클라이언트 측에서 볼 수 있다. 이는 올바른 *hydrate를 위해 필요하다. 그렇기에 props에 전달되는 정보가 민감한 정보가 함부로 전달되지 않도록 주의해야한다.
1. SSR, SSG, CSR이든 관계없이 모든 props에 해당한다.
2. hydrate: https://programmerkokkiri.tistory.com/232
when does getServerSideProps run
getServerSideProps는 오직 서버측과 연동하여 작용한다. (절대 브라우저측에서 작동하지 않는단다.)
만약 어떠한 컴포넌트(page = component로 의역함)에서 getServerSideProps를 사용한다면...
- getServerSideProps를 사용하는 컴포넌트페이지를 요청할때, 그요청하는 시간인 request time에 맞춰 바로 getServerSideProps가 작동한다. 그리고 요청된 페이지는 return된 props를 이용해 바로 pre-render된다.
- next/link 컴포넌트나 next/router컴포넌트에 의해 클라이언트측에서 getServerSideProps를 사용하는 페이지를
요청할때에는 서버측에 API request를 보내고, 그 request에 의해 서버에서 getServerSideProps가 작동한다. - getServerSideProps는 페이지를 render할때 사용될 JSON파일을 return해주며, 개발자가 추가적으로 작업해줘야하는 사항은 없다.
- next-code-elimiantion tool을 통해 클라이언트측에 제공되는 코드와 내가 작성한 코드를 비교해서 어떻게 번들되는지 확인할 수 있다.
- getServerSideProps는 page 단위로 export되며, 별도의 non-pages파일들에서는 export할 수 없다.
- getServerSideProps는 독립적인 함수로서 작성해야한다. 즉, 파일에 있는 컴포넌트함수 내에 작성하는 것이 아니라, 컴포넌트함수 바깥에 작성을 해줘야한다.
when should I use getServerSideProps?
getServerSideProps는 기본적으로 클라이언트가 request할때 작동된다. 그리고 저장되지도 않는다.
(저장하고싶다면 cache-control 헤더를 구성하여 페이지 캐시를 사용할 수 있다는데 이렇게 헤더를 구성하면 저장이 가능하기는 하다.)
(아래에 cache-control 헤더 사용 예시있음)
- 장점: 클라이언트가 request할때마다 정보를 받아오기때문에 최신의 정보를 가져올 수 있다.
- 단점: 매번 클라이언트가 request할때마다 정보를 가져오기때문에 페이지 로딩시간이 길어지고, 더 많은 서버 cost를 사용할 것이다.
getServerSideProps or API Routes
데이터를 가져오기 위해 API Route를 사용하고, 그 API Route를 getServerSideProps에서 직접 호출하는 것은 불필요하고 비효율적인 방법이다. 이렇게 하면 getServerSideProps와 API Route 모두 서버에서 실행되므로, 중첩적으로 요청이 발생하게 되는 것이다.
예를 들어, CMS에서 데이터를 가져오기 위해 API Route를 사용하는 경우, 해당 API Route를 getServerSideProps에서 직접 호출하는 것은 성능을 감소시키는 추가적인 호출을 유발할 수 있다. 이경우, API Route 내부에서 사용된 로직을 직접 getServerSideProps에 가져와 사용하는 것이 효율적이다.->(이는 CMS, 데이터베이스 또는 기타 API에서 직접 getServerSideProps 내에서 호출하는 것을 의미함)
즉, 데이터를 가져오기 위해 API Route를 사용하는 경우, API Route를 getServerSideProps에서 직접 호출하는 대신 필요한 로직을 getServerSideProps에 가져와서 사용하는 것이 더 효율적인 방법이다.
요약: getServerSideProps내에 API Route를 작성하면 중첩적인 요청이 이루지므로, API Route에서 사용할 로직만 빼다가 getServerSideProps내에 작성하는 것이 훨씬 효율적임
getServerSideProps with Edge API Routes
**Edge Runtime은 Next.js 애플리케이션을 실행하기 위한 서버 사이드 런타임 환경을 의미한다.
getServerSideProps는 서버리스환경과 *Edge runtime환경 모두에서 사용될 수 있다. 근데 Edge runtime에서 작동하면 returned된 응답 객체에 접근할 수 없다. (쿠키같은것들을 getServerSideProps내에서 추가할 수 없다는 뜻) 응답객체에 접근하기위해서는 Node.js런타임이어야 한다. (Next의 기본 런타임은 Node.js환경이다.)
페이지마다 런타임을 구성해줄 수 있는데, 방법은 아래의 코드와 같다.
export const config = {
runtime: 'nodejs',
}
Fetching data on the Client Side
만약 페이지가 빈번히 업데이트되는 데이터로 구성되어있고, *pre-render할 필요도 굳이 없다면 -> client-side에서 데이터를 받는 방법을 사용하면 된다.
- 즉각적으로 데이터없이 페이지를 보여줘야한다면 페이지의 일부분들은 Static Generation을 사용해 pre-render할 수 있다.
-> 데이터가 아직 받아지지 않은 경우 로딩화면을 띄워주면 된다. - 그런다음 client-side에서 데이터를 받아오면 그때서야 페이지를 보여주면 된다.
이러한 접근은 유저 대시보드같은곳에서 사용하면 좋다.
- 첫째, 유저의 대시보드는 private환경이고,
- 둘째, 유저의 대시보드는 SEO와 관련이 없는 페이지이고(pre-render장점중 하나가 SEO),
- 셋째, 유저의 대시보드는 굳이 pre-render될 필요가 없다.
- 하지만 client-side에서 데이터를 받아오게되면 매번 데이터가 업데이트되기때문에 그러한 매번의 fetching시간은 감수해야한다.
pre-render가 필요한 상황예시
1. SEO: 검색 엔진은 HTML 파일을 크롤링하여 웹 페이지를 검색 결과에 노출한다. SSR을 적용하지 않는 경우, 검색 엔진은 페이지의 초기 로딩 시점에는 빈 페이지를 읽어들일 수 있다. 이러한 경우 검색 엔진 최적화를 위해 프리 랜더링이 필요하다.
2. 초기 로딩 속도 개선: CSR은 초기 로딩 시간이 길어지는 단점이 있다. 이는 CSR이 모든 컴포넌트를 클라이언트에서 로드한 후 렌더링하기 때문이다. 이에 반해, 프리 랜더링은 초기 로딩 시간을 줄여 성능을 향상시킬 수 있다.
3. 모바일기기 최적화: 모바일기기는 CPU나 메모리 등의 성능이 PC보다 낮기 때문에 CSR의 초기 로딩 속도 문제가 더 크다. 프리 랜더링을 적용하면 모바일 기기에서의 성능을 개선할 수 있다.
4. 보안이슈: CSR은 클라이언트 측에서 코드를 실행하므로 보안상의 문제가 발생할 수 있다. 이러한 경우 프리 랜더링을 적용하여 보안을 강화할 수 있다.
Using getServerSideProps to fetch data at request time
getServerSideProps사용 예시이다.
function Page({ data }) {
// Render data...
}
// This gets called on every request
export async function getServerSideProps() {
// Fetch data from external API
const res = await fetch(`https://.../data`)
const data = await res.json()
// Pass data to the page via props
return { props: { data } }
}
export default Page
- 위에서 언급한대로 getServerSideProps함수는 컴포넌트 바깥에 위치해놓은 것을 확인할 수 있다.
Caching with Server-Side Renderting (SSR)
위에서 언급했던 부분이다.
caching headers(Cache-Control)을 getServerSideProps내에 첨부하여 저장할 수 있다는 부분
https://nextjs.org/docs/going-to-production(필요할때 SSR-caching부분 읽어보자.)
// This value is considered fresh for ten seconds (s-maxage=10).
// If a request is repeated within the next 10 seconds, the previously
// cached value will still be fresh. If the request is repeated before 59 seconds,
// the cached value will be stale but still render (stale-while-revalidate=59).
//
// In the background, a revalidation request will be made to populate the cache
// with a fresh value. If you refresh the page, you will see the new value.
export async function getServerSideProps({ req, res }) {
res.setHeader(
'Cache-Control',
'public, s-maxage=10, stale-while-revalidate=59'
)
return {
props: {},
}
}
Does getServerSideProps render an error page
만약 getServerSideProps를 사용하다가 에러가 난다면 자동적으로 pages/500.js를 보여준단다.
개발자모드에서는 이 파일이 사용되지 않고 개발용 오버레이가 표시된다는데 잘 모르겠다.
https://nextjs.org/docs/advanced-features/custom-error-page#500-page(필요할때 읽어보자.)
'Next.js(ver.12)' 카테고리의 다른 글
Docs_Data Fethcing(getStaticPaths) (0) | 2023.03.19 |
---|---|
Docs_Data Fethcing(SSG-getStaticProps) (0) | 2023.03.18 |
Getting Started (0) | 2023.03.16 |
Create a Next.js App (0) | 2023.03.16 |
From React to Next.js (0) | 2023.03.14 |