Next.js 렌더링 방법 이해: CSR, SSR, SSG, ISR

Next.js 렌더링 방법 이해: CSR, SSR, SSG, ISR
당신과 같은 독자는 MUO를 지원하는 데 도움이 됩니다. 귀하가 당사 사이트의 링크를 사용하여 구매할 때 당사는 제휴 수수료를 받을 수 있습니다.

렌더링은 React 코드를 HTML로 변환하는 프로세스입니다. 선택하는 렌더링 방법은 작업 중인 데이터와 성능에 대한 관심 정도에 따라 다릅니다.





Next.js에서 렌더링은 매우 다양합니다. 페이지를 클라이언트 측 또는 서버 측, 정적으로 또는 증분적으로 렌더링할 수 있습니다.





이러한 방법이 어떻게 작동하고 각각이 어떻게 수행되는지 살펴보십시오.





MAKEUSEOF 오늘의 비디오

서버 측 렌더링

SSR(서버 측 렌더링)을 사용하면 사용자가 웹 페이지를 방문하면 브라우저가 해당 페이지에 대한 요청을 서버에 보냅니다. 서버는 필요한 경우 데이터베이스에서 필요한 데이터를 가져와 페이지의 콘텐츠와 함께 브라우저로 보냅니다. 그런 다음 브라우저는 이를 사용자에게 표시합니다.

브라우저는 사용자가 클릭하는 모든 링크에 대해 이 요청을 수행합니다. 이는 서버가 매번 요청을 처리함을 의미합니다.



이것은 웹사이트의 성능을 저하시킬 수 있습니다. 그러나 서버 측 렌더링은 동적 데이터를 사용하는 페이지에 적합합니다.

getServerSideProps를 사용하여 사용자가 요청할 때마다 페이지를 다시 작성하십시오.





export default function Home({ data }) { 
return (
<main>
// Use data
</main>
);
}

export async function getServerSideProps() {
// Fetch data from external api
const res = await fetch('https://.../data')
const data = await res.json()

// Will be passed to the page component as props
return { props: { data } }
}

getServerSideProps는 서버에서만 실행되며 다음과 같이 실행됩니다.

  • 사용자가 페이지에 직접 액세스하면 요청 시 실행되고 페이지는 반환되는 소품으로 미리 렌더링됩니다.
  • 사용자가 다음 링크를 통해 페이지에 액세스하면 브라우저는 이를 실행하는 서버에 요청을 보냅니다.

새 버전에서는 페이지 또는 레이아웃에서 동적 데이터 가져오기를 사용하여 서버 측 렌더링을 선택할 수 있습니다.





동적 데이터 가져오기는 캐시 옵션을 'no-store'로 설정하여 캐싱을 구체적으로 선택 해제하는 fetch() 요청입니다.

Google 백업 및 동기화를 제거하는 방법
fetch('https://...', { cache: 'no-store' }); 

또는 revalidate를 0으로 설정합니다.

fetch('https://...', { next: { revalidate: 0 } }); 

이 기능은 현재 베타 버전이므로 염두에 두십시오. 동적 데이터 가져오기에 대한 자세한 내용은 Next.js 13 베타 문서 .

클라이언트 측 렌더링

데이터를 자주 업데이트해야 하거나 페이지를 미리 렌더링하지 않으려는 경우 클라이언트 측 렌더링(CSR)을 사용해야 합니다. 페이지 수준 또는 구성 요소 수준에서 CSR을 구현할 수 있습니다. 페이지 수준에서 Next.js는 런타임에 데이터를 가져오고 구성 요소 수준에서 완료되면 마운트 시 데이터를 가져옵니다. 이 때문에 CSR은 성능 저하에 기여할 수 있습니다.

사용 useEffect() 후크 다음과 같이 클라이언트에서 페이지를 렌더링하려면:

import { useState, useEffect } from 'react' 
function Home() {
const [data, setData] = useState(null)
const [isLoading, setLoading] = useState(false)

useEffect(() => {
setLoading(true)

fetch('/api/get-data')
.then((res) => res.json())
.then((data) => {
setData(data)
setLoading(false)
})
}, [])

if (isLoading) return <p>Loading...</p>
if (!data) return <p>No data</p>

return (
<div>
// Use data
</div>
)
}

SWR 후크를 사용할 수도 있습니다. 데이터를 캐시하고 오래된 경우에 대비하여 다시 유효성을 검사합니다.

import useSWR from 'swr' 
const fetcher = (...args) => fetch(...args).then((res) => res.json())
function Home() {
const { data, error } = useSWR('/api/data', fetcher)
if (error) return <div>Failed to load</div>
if (!data) return <div>Loading...</div>

return (
<div>
// Use data
</div>
)
}

Next.js 13에서는 파일 상단에 'use client' 지시자를 추가하여 클라이언트 컴포넌트를 사용해야 합니다.

"use client"; 
export default () => {
return (
<div>
// Client component
</div>
);
};

SSR과 CSR의 차이점은 데이터가 CSR의 클라이언트 측에서 페치되는 동안 SSR의 서버에서 모든 페이지 요청에서 데이터를 페치한다는 것입니다.

정적 사이트 생성

정적 사이트 생성(SSG)을 사용하면 페이지에서 데이터를 가져옵니다. 빌드 타임에 한 번. 정적 생성 페이지는 모든 페이지가 미리 빌드되기 때문에 매우 빠르고 성능이 좋습니다. 따라서 SSG는 판매 페이지나 블로그와 같은 정적 콘텐츠를 사용하는 페이지에 적합합니다.

Next.js에서는 정적으로 렌더링하려는 페이지의 getStaticProps 함수를 내보내야 합니다.

export default function Home({ data }) { 
return (
<main>
// Use data
</main>
);
}

export async function getStaticProps() {
// Fetch data from external API at build time
const res = await fetch('https://.../data')
const data = await res.json()

// Will be passed to the page component as props
return { props: { data } }
}

getStaticProps 내에서 데이터베이스를 쿼리할 수도 있습니다.

export async function getStaticProps() { 
// Call function to fetch data from database
const data = await getDataFromDB()
return { props: { data } }
}

Next.js 13에서는 정적 렌더링이 기본값이며 캐싱 옵션을 끄기로 설정하지 않는 한 콘텐츠를 가져와서 캐싱합니다.

async function getData() { 
const res = await fetch('https://.../data');
return res.json();
}
export default async function Home() {
const data = await getData();
return (
<main>
// Use data
</main>
);
}

에 대해 자세히 알아보기 Next.js 13의 정적 렌더링 문서에서.

증분-정적 생성

SSG를 사용하고 싶지만 정기적으로 콘텐츠를 업데이트하고 싶을 때가 있습니다. 이것이 증분 정적 생성(ISG)이 도움이 되는 곳입니다.

ISG를 사용하면 지정한 시간 간격 이후에 정적 페이지를 만든 후 정적 페이지를 만들거나 업데이트할 수 있습니다. 이렇게 하면 필요한 페이지만 전체 사이트를 다시 만들 필요가 없습니다.

ISG는 사용자에게 최신 콘텐츠를 제공하는 추가 이점과 함께 SSG의 이점을 유지합니다. ISG는 변화하는 데이터를 소비하는 사이트 페이지에 적합합니다. 예를 들어 다음을 수행할 수 있습니다. ISR을 사용하여 블로그 게시물 렌더링 게시물을 수정하거나 새 게시물을 추가할 때 블로그가 계속 업데이트되도록 합니다.

ISR을 사용하려면 페이지의 getStaticProps 함수에 revalidate prop을 추가하십시오.

export async function getStaticProps() { 
const res = await fetch('https://.../data')
const data = await res.json()

return {
props: {
data,
},
revalidate: 60
}
}

여기에서 Next.js는 60초 후에 요청이 들어오면 페이지를 다시 작성하려고 시도합니다. 다음 요청은 업데이트된 페이지에 대한 응답으로 이어집니다.

Next.js 13에서 다음과 같이 가져오기에서 revalidate를 사용합니다.

fetch('https://.../data', { next: { revalidate: 60 } }); 

데이터에 가장 적합한 시간 간격을 설정할 수 있습니다.

렌더링 방법을 선택하는 방법

지금까지 Next.js의 네 가지 렌더링 방법인 CSR, SSR, SSG 및 ISG에 대해 배웠습니다. 이러한 각 방법은 다양한 상황에 적합합니다. CSR은 강력한 SEO가 문제가 되지 않는 새로운 데이터가 필요한 페이지에 유용합니다. SSR은 동적 데이터를 소비하는 페이지에도 적합하지만 SEO 친화적입니다.

SSG는 데이터가 대부분 정적인 페이지에 적합하고 ISG는 간격으로 업데이트하려는 데이터가 포함된 페이지에 가장 적합합니다. SSG와 ISG는 데이터를 미리 가져오고 캐시할 수 있기 때문에 성능과 SEO 면에서 훌륭합니다.