[Next.js] 기초 다지기 1

dee·2022년 10월 31일
1

Next.js

목록 보기
1/3
post-thumbnail

🤔왜 React는 SEO가 힘들까?

Dom에서 보여지는 것과 내가 처음에 만든 오리지널 HTML과 차이가 있기 때문이다. 이는 React뿐만 아니라 SPA로 구현되는 페이지에서 나타나는 현상이다. 검색 엔진 봇이 코드가 동적으로 추가되는 HTML 수집을 못하기에 언급되는 문제이다. Next.js는 어떤 방식으로 이 SEO 최적화 문제를 해결하고 그 원리는 무엇인지 알아보자.


Next.js?

  • React로 서버사이드렌더링(SSR)을 구현할 수 있는 프레임워크.
  • 자체적으로 타입스크립트를 지원하기 때문에 따로 설정을 하지 않아도 됨.
  • 라우트에 해당하는 파일들을 pages 폴더 안에 저장해두면 Next.js가 빌드 과정에서 코드 스플리팅을 자동적으로 지원.
    🚨 pages 폴더는 지켜야할 필수 규칙!
  • pages안의 js/jsx/ts/tsx 파일들을 기반으로, 파일 이름과 같은 라우트로 페이지를 구성.
  • 동적인 라우팅은 대괄호를 사용하여 나타냄.
    🧷 [id].jsx

Next.js의 SEO

결론을 말하자면 Next.js를 통해 SEO 최적화가 가능하다. Pre-rendering로 검색 엔진 크롤러가 각 라우팅에 맞는 HTML을 수집할 수 있기 때문이다.
대부분의 검색 엔진 크롤러는 자바스크립트에 의해 동적으로 추가되는 코드를 수집하지 못한다. 이는 하나의 HTML를 가지고 UI를 새로 랜더링하는 SPA의 단점으로 뽑히고 있다. 그래서 React같은 경우도 아래의 표와 같이 빈 HTML만을 검색 엔진이 인식하게 된다.

프로그래밍 언어검색 엔진 크롤러가 수집하게 되는 HTML
React서버에서 들어온 비어있는 초기 HTML페이지만 보고 있게 됨.
Next.js기본적으로 모든 페이지를 Pre-rendering하여 각각의 페이지를 미리 HTML로 구성함.

Pre-rendering

  • Next.js에서 중요한 개념.
  • 클라이언트 사이드 자바스크트에 의해 HTML이 생성된는 것이 아니라 사용자에게 보여지기 전에 미리 각 페이지의 HTML를 생성하는 Next.js의 방식.
  • Pre-rendering은 퍼포먼스와 SEO를 좋게 해준다.

Pre-rendering 과정.

  1. Initial load
    • 사전 렌더링된 HTML을 보여준다.
  2. Hydration
    • 페이지가 자바스크립트와 상호작용이 되도록 한다. 이를 쉽게 이야기하면 컴포넌트의 태그들의 이벤트가 처리될 수 있도록 HTML과 자바스크립트를 연결해주는 것이다.

pre-rendering하는 두가지 형식.

퍼포먼스 이유로 Next.js공식 페이지에서는 static generation을 추천.

  1. static generation: build time될 때 HTML이 생성되고 각 요청에 재사용. 퍼포먼스를 증대하는 것없이 CDN에 의해 캐싱됨.
  2. server-side rendering : HTML이 각 요청에 생성.

client side data fetching을 위의 두 가지 형식으로 다 사용할 수 있다. 이것은 몇몇 페이지들이 클라이언트 사이드 자바스크립트에 의해 렌더될 수 있다는 것을 의미한다.
🚨 SEO가 필요없는 페이지라면 성능상 CSR로 처리하는 것이 좋음

🧐 CSR로 사용하기
useEffect를 사용하여 데이터 통신을 하면 CSR로 동작한다. 이는 렌더링이 된 이후에 데이터를 가져오기 때문이다.


Static Generation with data

페이지가 pre-renderfing을 위해 fetching된 데이터를 필요로 할 때 아래의 두 가지 방법으로 fetching된 데이터를 HTML에 적용시킬 수 있다.
🚨 일부 페이지는 데이터를 fetching하지 않으면 HTML 렌더링이 불가하다.

  1. getStaticProps
  • 페이지 컨텐츠가 데이터에 의존할 경우 사용.
  • 이 함수는 build time 때 호출하여 HTML 생성, pre-render할 때 page의 props로 fetch된 데이터를 전달한다.
  • Server Side에서만 동작, JS Bundle에도 포함되지 않음.
  • Development 모드에서 모든 요청마다 동작, Production에서는 build time에만 동작.
    🧷 request time에만 접근 가능한 데이터를 사용하지 못함.
function Blog({ posts }) {
	return (<>
        {posts.map(post => <Post post={post} />)}        
    </>);
}

export async function getStaticProps(){
	const res = await fetch(URL);
  	const post = await res.json();
    
    return { props: { posts }};
}

export default Blog;
  1. getStaticPath
  • 페이지의 paths가 데이터에 의존할 경우 사용.
function Post({ post }) {
  return <div>{post}</div>
};

export async funciton getStaticPaths(){
	const res = await fetch(URL);
  	const posts = await res.json();
  
  	const paths = posts.map((post) => ({
    	params: { id: post.id }
    }))
    
    return { paths, fallback: false }
}

export async funciton getStaticProps({ params }){
	const res = await fetch(URL/${params.id});
	const post = await res.json();
	
	return { props: { post }};
}

export default Post;

Static Generation without data

페이지를 렌더할 때 데이터가 필요없는 컴포넌트의 경우 build time때 HTML 페이지를 생성해버린다.

const App = () => {
	return <div>Hello World</div>
}

export default App;

Setver-side Rendering

  • 페이지 요청이 있을 때마다 HTML을 생성해주는 방식.
  • 사용자에 따라 페이지의 데이터가 변경되어야 할 경우 사용.
  1. getServerSideProps
  • build time 대신 모든 요청마다 실행.
  • getStaticProps와 비슷하지만 매 요청마다 실행한다는 것이 다른점.
export default function Page({ data }) {
  // Render data...
}

export async function getServerSideProps(){
  	const res = await fetch(URL);
  	const data = await res.json();
  
	return { props: { data }}
}

🍑 오늘의 공부일기

Next.js 단순히 파일 기반으로 라우팅을 한다는 것만 알았었다. 이 기능만이 장점이라고 생각했지만 자세히 그 원리를 파헤치니 이점이 많음을 조금씩 깨닫는다. 프로젝트를 진행해보면서 Static Generation과 SSR를 확실하게 이해해봐야겠다.


참고
https://nextjs.org/docs/basic-features/pages
https://wonit.tistory.com/362?category=829651
https://velog.io/@hyunjine/Pre-rendering
https://velog.io/@tunggary/Next.js-Data-fetching#static-generation-1

profile
웹 프론트엔드 개발자

0개의 댓글