CSR(Client Side Rendering)
브라우저가 (서버로부터) 처음에는 빈 HTML 파일만 받고 자바스크립트를 다운로드하여 리액트(자바스크립트) 실행하여 DOM 렌더링
작은 HTML만 받고 나머지는 자바스크립트로 동적으로 DOM을 그리므로 화면 깜빡임 없지만 초기 용량이 큼SSR(Server Side Rendering)
완성된 HTML이 서버에서 만들어진 뒤 브라우저에 전송되고 브라우저는 해당 HTML을 바로 렌더링 가능
SSG(Static Site Generation)
pre-rendering : static한(정적인) HTML을 build time에 미리 만들어 둔다 (cf. SSR은 request time에 <=> 사이트에 접속할 때마다)
SSR, CSR, SSG의 장점만 고려하여 페이지를 자유롭게 routing/rendering 할 수 있도록 API 제공
장점 : SSR/SSG - HTML의 작은 용량, 보안 / CSR - 페이지 이동 속도, 화면 깜빡임 없음
CRA vs Next.js : pre-rendering
개발 환경에서는 매 실행마다 getStaticProps가 실행됨
cf) production 서버 실행 : yarn build -> yarn start
port가 남아있을 경우 killall -9 node 실행 후 yarn start
변하지 않는 정적 파일 => 캐시에 HIT
build time에 API를 한 번만 불러오고 배포된 이후에는 그 값이 변하지 않는 경우 getStaticProp 사용하여 SSG 방식으로 렌더링
가끔씩 API의 결과가 바뀌는 경우 - revalidate: Incremental Static Regeneration(ISR)
이미 빌드가 완료된 사이트에서 주기적으로 정적인 페이지를 업데이트할 수 있게 됨
해당 페이지만 업데이트 하므로 전체 사이트 다시 빌드할 필요 없음
export async function getStaticProps() {
const delayInSeconds = 2;
const data = await new Promise((resolve) =>
setTimeout(() => resolve(Math.random()), delayInSeconds * 1000)
);
return {
props: { data },
revalidate: 5 // 5초마다(서버가 request를 받은지 5초가 지난 후, 다시 request가 왔을 때마다 getStaticProps() 함수를 다시 실행해서 만약 데이터가 바뀌었으면 새로운 값으로 다시 pre-rendering 하라
};
}
SSG에 비해 UX가 좋지 않으므로 request time마다 서버사이드에서 렌더링 해야 되는 페이지에만 적용
ex) 사용자의 인증정보에 따라 변하는 페이지, 페이지가 동적으로 변해야 하지만 보안은 중요한 페이지
함수 사용 X
기본적으로 페이지에 포함되는 컴포넌트(NoSSR)은 서버에서 렌더링 되어야 함
SSR로 렌더링하고 싶지 않은 컴포넌트가 있을 경우 일반적인 import문 대신 next/dynamic사용해서 import
최초 실행은 SSG로 실행되지만 페이지를 라우팅할 때는 CSR 방식으로 이동/DOM 렌더링
next/link가 있는 곳의 자바스크립트와 json 파일로 해당 페이지에 대한 정보를 미리 가져와서 CSR 방식으로 빠르게 라우팅
링크가 보이지 않을 때는 자바스크립트 파일을 불러오지 않음 (lazy한 방식으로 불필요한 네트워크 요청 지양)
next.js 13버전부터는 Link 태그가 a 태그 완전 대체 가능
export default function Links() {
const router = useRouter();
return (
<main>
<h1>Links</h1>
<button
onClick={() => {
router.push('/url');
})
>
/url
</main>
)
}
useRouter는 next/link 대체 가능
CSR 방식으로 라우팅
next/link처럼 링크 보일 때 자바스크립트 불러오지는 않음
=> next/link처럼 자동으로 prefetch 하기 위해서는 개발자가 직접 구현해주어야 함
useEffect(() -> {
router.prefetch('/이동하고자 하는 url');
}, [router]);
prefetch를 자동으로 해주지 않기 때문에 특별한 경우가 아니라면 next/link 사용 권장