23.02.03 Next.js

Gon·2023년 2월 3일
0

React

목록 보기
11/11
post-thumbnail

Next.js

웹 개발자에게 필요한 다양한 기능을 제공해주는 리액트 프레임워크

특징

  • 개발 환경 설정이 쉽고 간단하다.
  • SEO(Search Engine Optimization)을 위한 SSR(Server-Side rendering)을 지원한다.
  • 초기 로딩 속도 개선을 위한 자동 code splitting(코드 분할)을 지원한다.

Page와 Routes

Next.js에서의 페이지

// pages/about.js (1)
export default function About() {
	return <div>About Page</div>
}

// pages/about/index.js (2)
export default function About() {
	return <div>About Page</div>
}

// pages/index.js (3)
export default function Index() {
	return <div>Index Page</div>
}

페이지 이동

  • next/link
import Link from 'next/link'

function Home() {
  return (
    <ul>
      <li>
        <Link href="/">Home</Link>
      </li>
      <li>
        <Link href="/about">About Us</Link>
      </li>
      <li>
        <Link href="/blog/hello-world">Blog Post</Link>
      </li>
    </ul>
  )
}

export default Home
  • next/router
import { useRouter } from 'next/router'

function Home() {
  return (
    <ul>
      <li onClick={() => {router.push("/")}}>Home</li>
      <li onClick={() => {router.push("/about")}}>About Us</li>
      <li onClick={() => {router.push("/blog/hello-world")}}>Blog Post</li>
    </ul>
  )
}

export default Home

Dynamic Routes

// pages/post/[id]

import { useRouter } from 'next/router'

const Post = () => {
  const router = useRouter()
  const { id } = router.query

  return <p>Post: {id}</p>
}

export default Post

API Routes

Next.js 프로젝트에서 Node 서버 없이 api를 만들어 배포할 수 있도록 만들어주는 기능

// pages/api/hello.js

export default function handler(req, res) {
  res.status(200).json({ name: 'John Doe' })
}

Dynamic API Route

// pages/api/test/[id].js

export default function handler(req, res) {
  const { query } = req;
  const { id } = query;

  res.status(200).json({ name: "test", id });
}

Data Fetching

Rendering

Javascript를 이용해서 HTML 코드를 만드는 행위

Pre-rendering

Client에 HTML이 이미 로드가 된 이후가 아닌, 이전에 Javascript를 이용해 HTML을 만드는 것
Server-Side Rendering(SSR), Static-Site generation(SSG)

SSR

  • getServerSIdeProps
// pages/ssr/[id].js

import { useRouter } from "next/router";

const Post = ({ post }) => {
  const router = useRouter();
  const { id } = router.query;

  return (
    <div>
      Post: {id}
      <h2>{post.title}</h2>
      <p>{post.body}</p>
    </div>
  );
};

export default Post;

export async function getServerSideProps(context) {
  const { params } = context;
  const { id } = params;

  const response = await fetch(
    `https://jsonplaceholder.typicode.com/posts/${id}`
  );
  const post = await response.json();

  return {
    props: {
      post,
    },
  };
}

CSR vs SSR vs SSG vs ISR

  • CSR

    브라우저에서 HTML file을 로드하면, Javascript를 이용하여 rendering 하는 방식

  • SSR

    브라우저에서 해당하는 페이지를 접속하면, 그 순간 서버에서 html을 렌더링해서 전달해주는 방식

  • SSG

    SSR의 경우 페이지를 요청할 때마다 서버에서 렌더링 함
    정적인 페이지를 제공하려고 할 때는 그럴 필요없이,
    빌드할 때 렌더링하고 페이지를 요청할 때 이미 렌더링 된 페이지를 반환

  • ISR

    SSG는 컨텐츠가 업데이트 되면 제대로 된 정보를 보여줄 수 없음
    이를 보완하기 위해서 일정 주기마다 페이지를 빌드시켜주는 ISR이라는 방식이 있음

  • 비교

CSRSSRSSGISR
빌드 시간짧다짧다길다길다
SEO나쁨좋음좋음좋음
페이지 요청에 따른 응답 시간보통길다짧다짧다
최신 정보인가?맞음맞음아님아닐 수 있음

SSG

  • getStaticProps
    SSG를 원하는 페이지에 getStaticProps를 추가하면, 해당 페이지는 빌드할 때 렌더링 됨
    export async function getStaticProps(context) {
     return {
       props: {}, // will be passed to the page component as props
     }
    } 
- getStaticPaths
 getStaticProps을 이용하는 페이지에서 dynamic routes를 제공하기 위해서 사용
 ```jsx
 // pages/posts/[id].js

export async function getStaticPaths() {
  return {
    paths: [{ params: { id: '1' } }, { params: { id: '2' } }],
    fallback: false, // false, true, "blocking"
  }
}

export async function getStaticProps(context) {
  return {
    props: { post: {} },
  }
}

export default function Post({ post }) {
  // ...
}
  • fallback
    • false
      • getStaticPaths에서 제공하지 않은 페이지는 모두 404로 연결
    • true
      • getStaticPaths에서 제공하지 않은 페이지를 요청한 경우,
        fallback 페이지를 보여주다가, 해당 페이지를 서버에서 생성을 한 이후에 보여줌
    • blocking
      • getStaticPaths에서 제공하지 않은 페이지를 요청한 경우,
        페이지를 서버에서 생성을 한 이후에 보여줌

ISR

getStaticProps에 revalidate 속성만 추가

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

  return {
    props: {
      posts,
    },
    revalidate: 10, 
  }
}

SEO(Search Engine Optimization)

구글, 네이버 등 검색 엔진에서 사이트를 찾기 쉽도록 사이트를 개선하는 작업

크롤링

  • robots.txt 파일 설정
    • 웹 크롤러와 같은 로봇들의 접근을 제어하기 위한 규칙 파일
    • /public 폴더 안에 넣어줌
  • sitemap.xml 제출
    • next-sitemap같은 라이브러리를 이용해 생성
    • Google Search Console에 제출

인덱싱

  • Meta tag 설정
    • <Head> 컴포넌트를 이용해서 _app.js 파일 및 페이지 파일에 Meta tag 설정
  • Open Graph 설정
    • Open Graph
    • <Head> 컴포넌트를 이용해서 _app.js 파일 및 페이지 파일에 Meta tag 설정
  • semantic tag 사용
    • 의미를 가지는 태그 사용
      • header/footer/section/nav 등

Web Vitals

LCP(Largest Contentful Paint)

페이지의 로딩 성능을 측정하는 항목

FID (First Input Delay)

페이지의 응답성을 측정하는 항목

CLS (Cumulative Layout Shift)

시각적 안정성을 측정하는 항목

Chrome Lighthouse로 측정

Middleware

앱 사이에 있는 소프트웨어

Next.js

Next.js의 경우, 특정 페이지로 이동을 해서 요청을 보냈을 때,
그 요청에 대한 응답을 받기 전 Middleware를 통해 다양한 작업을 할 수 있음
예시)

  • 비로그인 유저 제한
    • request에 존재하는 cookie를 검사해서, 비로그인 유저를 검사
  • redirect
    • 특정 URL을 서버에서 바로 리다이렉트
  • rewrite
    • 특정 URL을 보여주면서, 다른 페이지를 보여주고 싶을 때 사용

0개의 댓글