1. SSR
- 서버에서 HTML 코드를 동적으로 렌더링하고 웹 브라우저로 전송
- 하이드레이션: 렌더링한 페이지에 스크립트 코드를 집어넣어서 나중에 동적으로 처리
- 장점
- 보안성: 서버에서 쿠키, 주요API, 데이터 검증등이 이루어지기 때문에 더 안전함
- 호환성: 클라이언트 환경이 좋지 못해도 웹 페이지 제공 가능
- 뛰어난 SEO
- 단점
- 클라이언트가 요청할 때마다 페이지를 다시 렌더링할 수 있는 서버가 필요
- 브라우저 전용 API를 사용해야하는 컴포넌트가 있으면 명시적으로 지정해야함
- window, document 같은 객체 미제공
→ 더 많은 자원 소모, 요청 처리시간 증가, 이동시간 증가
데이터 가져오기
- getServerSideProps() 비동기 함수
- 페이지 요청시 이 함수를 먼저 호출 후 서버에서 실행
- 이 함수는 props 객체를 컴포넌트로 전달하여 서버와 클라가 모두 접근하도록 함
export async function getServerSideProps() {
const userRequest = await fetch('url');
const userData = await userRequest.json();
return {
props: {
user: userData,
},
};
}
function IndexPage(props) {
return <div>{props.user.name}</div>;
}
2. CSR
- 서버가 웹 애플리케이션이 필요로하는 스크립트와 스타일만 포함된 기본 HTML만 마크업하고, 실제 렌더링은 웹 애플리케이션에서 이루어짐
- 장점
- 쉬운 페이지 전환: 새로고침할 필요 없고, 페이지 전환에 효과 넣을 수 있음
- 지연된 로딩과 성능: 모달은 HTML 마크업으로 존재하지 않음
- 서버 부하 감소: 전체 렌더링 과정이 브라우저에서 일어나기 때문에 서버리스 환경에서 앱 제공 가능
- 단점
- 네트워크 속도가 느릴때 전체 자바스크립트 코드와 CSS 파일을 받는것이 오래걸릴 수 있음
- SEO 성능 낮음
useEffect 훅
- Next.js가 useEffect를 리액트 하이드레이션 이후 브라우저에서 실행하도록 하면 특정 작업을 반드시 클라이언트에서 하도록 강제할 수 있음
- Next.js에서 브라우저 전용 API에 접근할때 해당 호출을 useEfeect로 감싸면 해당 함수를 클라이언트에서 호출하고 실행되도록 함 (useState를 함께 써서 특정 컴포넌트를 클라이언트에서 렌더링하도록 지정할 수도 있음)
process.browser 변수
dynamic()
- 브라우저 코드를 실행하는 경우에만 컴포넌트 렌더링하는 방법
- 이 코드를 실행하면 동적 임포트로 불러옴
💡 관리자 페이지나 비공개 프로필 페이지같이 검색엔진 신경쓸 필요없는 동적 웹페이지 만들고 싶을때는?
3. SSG (정적 사이트 생성)
- 일부 또는 전체 페이지를 빌드 시점에 미리 렌더링
- 변하지 않는 페이지를 미리 렌더링해서 HTML 마크업 형태로 제공
- 리액트 하이드레이션에 의해 정적페이지에서도 사용자와 상호작용 가능
- 장점
- 쉬운 확장: 정적페이지라서 서버에 부하를 주지 않음
- 뛰어난 성능: 빌드 시점에 HTML을 미리 렌더링하기때문에 웹 서버는 정적 파일을 보내기만하고 클라이언트 브라우저는 파일을 받아서 표시만함
- 더 안전한 API 요청: 필요한 모든 정보가 빌드 시점에 미리 페이지로 렌더링되어있기 때문에 보호해야할 데이터에 접근할 일 없음
- 단점
- 웹 페이지를 만들고 나면 다음 배포 전까지 내용이 변하지 않음 → ex) 블로그 글을 올렸는데 제목에 오타가 있어서 수정할 경우 단어 하나 수정하기 위해 데이터를 가져오고 정적페이지를 다시 생성해야함
⇒ 증분 정적 재생성(ISR) 방법으로 해결 가능
4. ISR (증분 정적 재생성)
- Next.js가 어느정도의 주기로 정적 페이지를 다시 렌더링하고 해당 내용을 업데이트할지 정할 수 있음
- ex) 엄청 많은 데이터를 가져와야하는 복잡한 대시보드 만들 때, 데이터가 자주 변하지 않는다면 SSG, ISR을 사용하여 데이터를 10분동안 캐싱
export async function getStaticProps(){
const userReq = await fetch('api/user');
const userData = await userReq.json();
const dashboardReq = await fetch('/api/dashboard');
const dashboardData = await dashboardReq.json();
return {
props: {
user: userData,
data: dashboardData,
},
revalidate: 600
};
}
function IndexPage(props) {
return (
<div>
<Dashboard user={props.user} data={props.data} />
</div>
);
}
export default IndexPage;
getStaticProps()
- 빌드 과정에서 페이지를 렌더링할때 이 함수를 호출해서 필요한 데이터 등을 가져오며 다음번 빌드 시점까지 더 이상 호출하지 않는다.
- revalidate 옵션을 통해 페이지에 대한 요청이 발생할 때 어느정도 주기로 새로 빌드해야하는지 나타냄
→ 10분이 지나고 해당 페이지에 요청이 들어오면 서버에서 다시 렌더링하고 getStaticProps()를 다시 호출함
- 10분이 지난 후 새로운 요청이 없다면 새로 빌드하지 않음
- Next.js에서는 어떤 페이지를 빌드 시점에 정적페이지(SSG)로 만들지 페이지 요청 시점(SSR)에 만들지 지정할 수 있음
- SSG와 ISR을 사용하면 SSR과 SSG를 함께 사용할 수 있음
출처: 실전에서 바로 쓰는 Next.js