빌드시스템이란 코드상의 로딩한 모듈의 의존성을 해결하고 실행가능한 JS 형식으로 변환하는 구조임
대표적인게 웹팩, ES 모듈 기반으로 라이브러리 배포등에 사용되는 rollup.js 이나 Next.js에서도 채용된 고속의 러스트기반 SWC라는 빌드도구도 등장함.
1.서버측에서 미리 렌더링된 html을 반환한다.
2. 브라우저에서 정적인 html로 표시한다.
3. 자비스크립트 chunk들 로드 => hydration 과정 발생
4. 동적인 리액트 어플리케이션으로 작동한다.
SSG, SSR에서 리액트 컴포넌트의 렌더링은 브라우저에 반환되기전, 즉 서버사이드에서 실행됨
클라이언트 측에서는 interactive 한 리액트 애플리케이션으로서 작동하도록 하기 위해 서버 측에서 미리 생성된 정적인 HTML 다운로드 한 뒤 동적인 리액트 컴포넌트로 복원함. => 이때 INTERACTION이 가능함.
Next.js에서는 Pre-Rendering된 웹페이지를 클라이언트에게 보내고 나서, 바로 리액트가 번들링된 자바스크립트 코드들을 클라이언트들에게 전송한다.
이게 가장 큰 장점 => 만약 CSR에서 JS파일이 disabled 된다면? 사용자는 화면을 볼 수 없다. 그러나 Next.js는 프리렌더링으로 이를 방지한다.
React 응답
=> 빈 html + 번들 받아옴 + 코드스플릿팅했다면 페이지 이동시 컴포턴트를 받아옴
pre rendering시 getStaticProps을 사용하면 사이트를 배포 때 정의하는 props를 사용해서 사이트를 생성하게 됨 => cdn에 의해 캐싱되어 재사용됨.
Next.js 응답
먼저 document Type의 파일을 응답받고 (pre-rendering) React로 번들링 된 JS파일들을 Chunk 단위로 전달 후 재 랜더링이 일어남.
즉 html 자체가 변하는 방식(기본적으로 ssr방식으로 동작)
페이지 이동 및 동작이 발생하는 경우에는 CSR 방식을 통해서 서버를 거치지 않고 브라우저에서 페이지를 이동한다. (Next.js의 Link 컴포넌트에 의해 가능함)
CSR방식으로 이동시 필요한 JS파일만 불러옴. GetStaticProps에 관련된 데이터들
아래와 같이 4가지 경우의 경우 다시 pre-Rendering이 발생함.
javascript 에서 location.href 으로 페이지를 이동했을 경우
html 에서 a 태그의 href 으로 페이지를 이동했을 경우
브라우저 주소창에 url 을 입력하여 해당 페이지에 접근 했을 경우
새로고침 했을 경우
Next.js 공식문서 페이지
SSG Cache Hit (https://vercel.com/docs/edge-network/headers)
이 헤더의 값은 응답이 Vercel의 에지 캐시에서 제공되었는지 여부를 나타냅니다.
제공되는 콘텐츠가 정적이거나 Cache-Control 헤더를 사용하는 경우 다음 값이 가능합니다.
MISS: 엣지캐시에서 응답을 찾지 못하고 오리진서버에서 가져온 응답입니다.
HIT: 응답이 엣지 캐시에서 제공되었습니다.
STALE: 응답이 엣지 캐시에서 제공되었습니다. 콘텐츠를 업데이트하기 위해 원본 서버에 대한 백그라운드 요청이 이루어졌습니다.
PRERENDER: 응답이 정적 저장소에서 제공되었습니다.
REVALIDATED: 원본 서버에서 응답이 제공되었으며 수신 요청에서 사용자의 인증으로 인해 캐시가 새로 고쳐졌습니다.
develoopment 환경에서는 항상 getStaticProps를 실행함.
API 호출결과가 달라질때는 ? => revalidate 값을 지정해서 사용함.(stale, fresh개념)
호출된 api결과가 stale한 상태라면 재호출해서 최신값을 가져옴
이것이 ISR방식(Increment Static Generation) => 빌드가 완료된 상태에서도 주기적으로 페이지 업데이트 가능함.
data가 변하지 않는다면? Next.js는 프리렌더링 즉 stale하지만 프리렌더링을 다시 수행하지 않음.
import type { NextPage } from 'next';
interface Props {
data: number;
}
const Example: NextPage<Props> = ({ data }) => {
return (
<main>
<h1>getStaticProps Page</h1>
<p>값: {data}</p>
</main>
);
};
export default Example;
export async function getStaticProps() {
const delayInSeconds = 2;
const data = await new Promise((resolve) =>
setTimeout(() => resolve(Math.random()), delayInSeconds * 1000)
);
return {
props: { data },
revalidate: 5 /** https://nextjs.org/docs/basic-features/data-fetching/incremental-static-regeneration */,
};
}
매 요청마다 페이지에 대한 html 문서를 렌더링하여 클라이언트에게 전달하는 방식입니다. getServerSideProps 함수를 정의하면 해당 페이지는 항상 매 요청마다 html 문서를 Pre-Rendering 하게 됩니다.
Next.js 공식문서에서는 Static Generation (SSG) 방식을 권장하고 있었습니다.
사용자의 인증정보에 따라 변하는 페이지이거나 보안이 중요한 페이지에 적용
const NoSSR = () => {
return <p>width: {window.innerWidth}</p>;
};
export default NoSSR;
dynamic import 말고 그냥 import를 한다면?
에러발생. 페이지에 포함되는 컴포넌트는 서버에서 렌더링이 되야함. => window 객체에 접근 불가능함. document도 마찬가지
결국 next server에서 프리렌더링을 진행하기 때문.
import type { NextPage } from 'next';
import { useEffect, useState } from 'react';
import dynamic from 'next/dynamic';
/** https://nextjs.org/docs/advanced-features/dynamic-import#with-no-ssr */
const NoSSR = dynamic(() => import('../../components/section1/NoSSR'), {
ssr: false,
}); // 이 구문이 없다면 에러뜸
const Example: NextPage = () => {
const [data, setData] = useState(0);
useEffect(() => {
const delayInSeconds = 2;
new Promise<number>((resolve) =>
setTimeout(() => resolve(Math.random()), delayInSeconds * 1000)
).then((result) => setData(result));
}, []);
return (
<main>
<h1>Client-side data fetching</h1>
<p>값: {data}</p>
<h1>no SSR</h1>
<NoSSR />
</main>
);
};
export default Example;
// 머릿 글자의 I는 인터페이스임을 나타내기 위한 것이다
interface IUser {
name: string;
age: number;
sayHello: () => string; // 인수 없이 문자열을 반환한다
}
class User implements IUser {
name: string;
age: number;
constructor() {
this.name = ''
this.age = 0
}
// 인터페이스에 정의되어 있는 메서드를 구현하지 않으면, 컴파일 시 에러가 된다
sayHello(): string {
return `안녕하세요. 저는 ${this.name}이며, ${this.age}살입니다.`
}
}
const user = new User()
user.name = 'Hana'
user.age = 36
console.log(user.sayHello()) // '안녕하세요. 저는 Hana이며, 36살입니다.'
ref)
hydration :https://www.howdy-mj.me/next/hydrate
https://helloinyong.tistory.com/315
https://velog.io/@wooseok123/Next.js-CSR-vs-
https://funveloper.tistory.com/164