SSR - Next.j
2023. 2. 1. 09:49ㆍ개발/실무용 메모
서버사이드 렌더링 개요
- 서버에서 페이지를 그려 클라이언트(브라우저)로 보낸 후 화면에 표시 하는 기법
- 이동 할때 마다 새로운 페이지 요청
- 완성된 페이지 형태로 응답
- 페이지 이동시 화면이 깜빡 거림
SSR vs CSR
- SSR 장점
- 초기에 HTML만 렌더링하여 보여주기때문에 초기 로딩속도가 빠름
- 검색엔진(SEO) 최적화가 가능
- SSR 단점
- 서버에서 처리를 해주기 때문에 서버에 부하가 발생할 수 있음
- SPA는 기본적으로 CSR 방식이 기본
- React에는 Next, Gatsby 등 도입하여 SSR 방식을 겸함
- Vue에는 Nuxt가 SSR 지원
Next.js
Next.js 란?
- 공식 홈페이지 링크
- Vercel 에서 제작한 리액트를 서버사이드렌더링(SSR)으로 쉽게 구현할수 있도록 환경을 제공해주는 리액트 프레임워크.
- 초기화면은 서버에서 받아와 렌더링 (SSR/SSG) 을 하고 그이후 라우팅 방식은 CSR방식으로 동작.
- SPA(React)는 기본적으로 CSR로 동작
- Next에서 pre-rendering을 빌드 타임에 한번만 하면 SSG(또는 SG), 유저 요청 때 마다 HTML 문서를 생성해서 반환하면 SSR
- SSG
- 데이터 없이 SSG
- 데이터 함께 SSG
- SSR
- SSG
- SSR and SSG 하이브리드
- Next.js 는 기본적으로 Node 서버를 띄워서 사용자가 진입할때 마다 페이지를 만들어낼수 있는데, export 기능으로 Static Site Generator 로 사용 가능.
- 빌드 시점에 미리 진입 할 수 있는 Page 를 파악하고, 이를 각각 HTML로 만들어냄. 이렇게 만들어진 static 파일(html, css, js)들은 s3 같은 호스팅 서버에 업로드하여 사이트를 구성 할 수 있음.
- SSG는 퍼포먼스에 집중 (CDN을 통해 더 빠른 응답 가능), 마케팅 페이지 / 블로그 게시물 / 제품의 목록 등과 같이 정적 생성하여 각 요청에 동일한 문서를 반환할 수 있는 경우 권장
- SSR은 항상 최신 상태를 유지해야 하는 경우 (요청에 따라 응답해야 할 내용이 시시각각 변함), 제품의 상세 페이지 / 분석 차트 등 요청 마다 다른 내용 또는 형식의 HTML 문서가 반환되는 경우 사용
기본 설치 & 실행 & 세팅
- 리액트와 리액트돔을 별도로 설치후 Next.js 설치
- package.json 의 scripts 영역에 next 명령어를 세팅해주면 시작 가능
// package.json
"scripts": {
"start": "next",
}
- pages 폴더를 생성하고 page가 될 index.js 파일을 세팅해 줌
function Index (props) {
const { message } = props;
return <div>
Welcome to {message}
</div>;
};
export async function getStaticProps(context) {
return {
props: {
message: `Next.js!`
}
};
};
export default Index;
- Static Site 로 배포하기 위해서는 각각의 페이지와 파일들을 export 기능으로 빌드 하도록 설정 해야함.
// package.json
"scripts": {
"build": "next build && next export",
}
- 또는 CNA(Create-Next-App) CLI로 설치
npx create-next-app 프로젝트 이름
- CRA(Create-React-App) vs CNA(Create-Next-App) 비교
- 타입스크립트 또한 처리가 가능하므로 함께 설치하여 사용하면 됨
npm init -y
npm install next react react-dom — save
npm install typescript @types/react @types/node — save-dev
페이지 추가
- pages 폴더 밑의 폴더와 파일들이 곧 페이지 경로가 됨 (automatic routing)
- automatic code splitting
- 리소스가 임포트 된것들을 분석하여, 로딩한 페이지가 꼭 필요로하는 JS파일만 로드함.
- automatic code splitting
디렉토리
--src
--pages //실제 보여지는 페이지. 각각의 파일이 하나의 route에 매핑된다.
--Step1.res
--Step2.res
--...생략
페이지에 동적 데이터 추가 (getStaticProps)
- 페이지를 빌드 하는 시점에서 필요한 데이터가 있을 때 사용. 즉, 빌드 시점에 API 값을 조회하고, 그 값을 페이지에 전달하여 생성함.
- 브라우저가 아닌 Node 상에서 API 를 조회하는것이므로 fetch 대신 node-fetch 를 사용해야함.
- 빌드시 고정되는 값으로, 빌드 이후에는 변경 불가.
- 예시
function Index({ data }) {
//렌더링될 함수
return <div>{data.message}</div>
}
//이 함수는 빌드 될때 실행됨
export async function getStaticProps() {
const res = await fetch('https://.../posts')
const data = await res.json()
return { //'data' 라는 props를 빌드 때 얻음.
props: {
data,
},
}
}
페이지 이동 (Link)
- next.js 에서의 페이지 이동으로 사용되는 태그, 처음 SSR로 만들어진 페이지에서 다른 페이지로 이동할 때 JSON으로 필요한 데이터만 변경하여 렌더링 하는 방식을 적용하게 해줌.
- 단독으로 사용할 수 없고 href 를 전달할 child element 가 존재해야 함.
- 태그로 이동하면 서버에 페이지를 새로 요청을 하고 번들파일을 다시 받지만 link 태그를 사용하여 이동하면 서버 요청을 하지 않는다. ⇒ a 태그는 전혀 다른 사이트로 페이지를 이동시켜 다시 돌아오지 않는 경우에 사용하고, 그외에는 모두 Link 태그를 사용한다.
- 사용 예시
import Link from "next/link";
const Index = () => {
<div>
<Link href="/step01">
<a>step01</a>
</Link>
</div>
}
getInitialProps
- React , Vue 의 Client Side Rendering (CSR) 의 경우는 useEffect, created 함수를 사용하여 data fetching 을 하지만, 서버사이드에서 실행하는 next에서는 getInitialProps 를 이용하여 진행한다.
- next v9 이상에서는 이러한 preRendering 에서 getInitailProps 대신 getStaticProps, getServerSideProps 를 사용한다.
- 참조 링크
getServerSideProps
- 빌드와 상관없이, 매 요청시마다 데이터를 서버에서 가져옴