Dynamic rendering / Static rendering

정중식·2023년 5월 2일

넥스트

목록 보기
5/5

Dynamic rendering / Static rendering

Next.js 옛날 버전에서는 SSG,ISR 이라 불렸다.

  • Next.js에서 페이지를 하나 만들면 기본적으로 스태틱 랜더링식으로 페이지를 보여준다.

  • 페이지안에 fetch나, 이런 비슷한 함수가 없는 일반페이지들은 기본적으로 스태틱 랜더링으로 동작하게 되어있다.

  • 페이지 안에 다음 코드들을 같이 작성해주면 다이나믹 랜더링으로 페이지를 바꿔줄 수 있다.

- fetch('/URL', { cache: 'no-store' }) 로 데이터 가져오는 문법 

- useSearchParams(), cookies(), headers() 

- [dynamic route]

- export const dynamic = 'force-dynamic' 

등등..
  • 참고로 fetch는 next.js에서 {cache: 'force-cache'}가 자동으로 들어가있다. 그렇기때문에, 매번 새로운 데이터를 가져와야한다면 { cache: 'no-store'}를 작성해줘야한다.

static rendering

npm run build 입력해주면 html 페이지들을 만들어주는데, 유저가 접속할 때 마다 그걸 그대로 보여준다.
페이지 안에 별 기능 없이, 매번 html 페이지를 새로 만들 필요가없이 그대로 보여주기 때문에 매우 빠르게 페이지 전송이 가능하다.
(유저 100명이 와도 페이지를 새로 만들지 않는다.)

dynamic rendering

유저가 페이지 접속할때마다 html 새로 만들어서 보내줌
그렇기때문에 서버 부담이 심해질 수 있다.
'캐싱' 기능으로 서버자원을 절약해줄 수 있다.

static rendering / dynamic rendering 강제로 바꾸기

  • npm run build를 하면 λ (람다) 표시와 ㅇ표시가 나온다.

  • λ로 표시되면 dynamic rendering

  • ㅇ로 표시되면 static rendering을 해준다.

  • 최상위 layout.js에서 getServerSession() 쓰면 모든 페이지가 아마 λ 일 수 있다.

사진 속 /list 페이지는 글작성하고, 삭제하면 바로바로 보여줘야하는 페이지이기 때문에, 다이나믹 랜더링페이지여야 하는데, 지금은 스태틱 페이지로 표시되어있다.

이 페이지를 다이나믹 랜더링으로 하고싶을때 다음과 같은 방법을 쓸 수 있다.

export const dynamic = 'force-dynamic' 

export default function 페이지(){
  (생략)
}
  • 'force-dynamic'를 넣으면 다이나믹 랜더링을 해준다.

  • 'force-static'를 넣으면 스태틱 랜더링을 해준다.

  • 'auto'를 넣으면 자동으로 알아서 판단해준다. (디폴트 값)

  • 결론은 배포하기전, npm run build를 하고 그 때 페이지들이 다이나믹/스태틱 랜더링으로 원하는대로 동작중인지 잘 살펴보면 되겠다.

캐싱기능(fetch)

  • 매번 데이터를 서버에서 가져오는게 아니라, 한번 가져온 결과를 어딘가에 저장해두고 그걸 꺼내온다.

  • 서버 API또는 DB응답을 기다릴 필요가 없기 때문에 훨씬 빠르게 데이터를 가져올 수 있게된다.

  • Next.js에선 쌩자바스크립트의 fetch() 기본함수를 업그레이드해놔서 사용가능한 문법이다.

  • server component 안에서만 캐싱기능 사용가능

Ex) GET 요청 결과 캐싱..

export default async function 페이지(){
  let result = await fetch('/api/어쩌구', { cache: 'force-cache' })
 }

fetch() 사용시 cache:'force-cache' 설정을 넣어두면 캐싱해주고, 앞으로 /URL로 요청할 때 마다 계속 캐싱된 결과를 가져와준다.

사이트 다시 npm run build 하기 전 까지 캐싱된걸 평생 보여준다.
(참고로 fetch 디폴트 값은 cache:'force-cache'로 설정되있음)

  • revalidate
fetch('/URL', { next: { revalidate: 60 } }) 

fetch()안에서 revalidate 옵션도 적용 할 수 있다.

이렇게 해주면, 캐싱 결과를 60초 동안만 보관하고 사용한다.

60초가 지나면 다시 /URL로 새로 요청해서 결과를 가져오고 캐싱해준다.

fetch('/URL', { cache: 'no-store' }) 

캐싱기능을 안쓰겠다는 뜻이다.

매번 코드를 읽을 때 마다 서버로 요청해서 데이터를 새로 가져온다.

주로 실시간 데이터가 중요한곳에서 쓰인다.

페이지 단위 캐싱

다음 코드처럼 connectDB를 사용해서 DB입출력 코드를 써놓은건 캐싱을 어떻게해야할까?

const Home = async () => {
  let client = await connectDB;
  const db = client.db('fourm');
  let result = await db.collection('post').find().toArray();


  return (
   ....
  );
};

export default Home;
  1. GET요청시 DB데이터 보내주는 서버 API 만들고, fetch()를 사용해준다.

  2. revalidate 옵션을 사용해서, 페이지 단위로 캐싱을 한다.
    (revalidate옵션 넣어서 페이지만들던거를 예전 Next.js에서 ISR이라고 불렸다.)

이 두가지 방법이있다. 2번 방법에 대해서 알아보면,

(아무 page.js 파일)

export const revalidate = 60;

export default function Page() {
   let client = await connectDB;
  const db = client.db('fourm');
  let result = await db.collection('post').find().toArray();


  return (
    ...
  )
} 

page.js 파일 위쪽에 revalidate 변수 하나 만들고, 원하는 초 단위 집어넣으면 특정 페이지를 원하는 시간 만큼 캐싱해둘 수 있다.

위의 코드처럼 적으면 60초 동안은 이 페이지 접속시 아무리 새로고침해도 미리 캐싱된 페이지를 보여준다.

60초가 지나면 페이지를 재생성해서 캐싱해준다.

(참고사항)

  • 60초마다 자동 재생성은 아니고, 방문자가 있어야 페이지를 재생성해준다.

  • 어떻게보면,60초마다 스태틱 랜더링 페이지 하나를 생성해주는 식이다.

  • 60초 지나기 전에 페이지 강제로 새로 만들라고 명령 줄 수 있다.
    ( on-demand revalidation )

  • 서버 API 기능 만들 때도 revalidate 옵션기입이 가능하다.

중복 fetch

여러 컴포넌트에서 같은 /url로 fetch하는 경우, 중복은 알아서 제거된다.

그래서 여러 컴포넌트에서 같은 /url로 요청하는 fetch() 많이 사용해도 비효율 문제가 딱히 없다고 한다.

그래서 컴포넌트가 많은 경우 변수나 state 공유문제도 자동으로 해결된다.

profile
내 가치를 찾아서

0개의 댓글