[NEXT JS] Data Fetching

Now, Sophia·2022년 7월 26일
0

TIL_NEXT.JS

목록 보기
3/4
post-thumbnail

CSR (Client Side Rendering)

클라이언트에서 렌더링을 하는 방식으로 유저가 페이지에 들어오면 클라이언트가 서버로 데이터를 요청한다.
그 사이 빈 html로 먼저 렌더가 되고, 그 후에 서버로부터 데이터를 받아 페이지를 그려낸다.
데이터(HTML, JS)를 받을 때까지 화면은 빈화면만 띄워진다.
그래서 데이터를 받아올 때까지의 첫 로딩 시간은 오래걸리고, 데이터가 없기 때문에 SEO에 취약하다.
하지만 모든 스크립트들을 한 번에 불러오기 때문에 이후로부터는 SSR보다 로딩시간이 짧다.

SSR (Server Side Rendering)

서버에서 렌더를 마친 데이터(HTML,JS)를 클라이언트에 보내는 방식으로 이미 렌더가 가능한 상태에서 브라우저에서 렌더가 되기 때문에 SEO 대응에 최적화 되어있다.
브라우저 렌더링은 HTML,CSS,Javascript 파일을 받아와 파싱하고 화면을 그려내는 것을 뜻하지만, 서버사이드렌더링은 HTML 파일에 내용이 있으면 렌더가 된 것을 뜻한다.
그래서 HTML 파일에 내용이 있어 브라우저가 페이지를 렌더링하기때문에 유저에게 바로 보여지는 것이다.
그 다음에 브라우저가 자바스크립트 파일을 다운 받고, 해당 파일을 실행 시키면 페이지의 상호작용이 가능해 지는 것이다.
CSR은 앞서 말했듯이 첫 페이지를 로딩할 때 모든 스크립트를 한 번에 받아왔기 대문에 다른 페이지로 이동했을 때 화면 렌더가 빠르지만,
SSR은 각 페이지마다 불러오기 때문에 첫 페이지를 로딩한 후에 다른 페이지 이동 후에도 첫 페이지를 로딩한 과정을 정확하게 다시 실행한다.
그래서 페이지 이동 시에도 똑같이 로딩 시간이 걸린다.
SSR은 매번 서버에 요청을 하기 때문에 서버 자원을 더 많이 사용한다.

SSG (Static-Site-Generation)

렌더를 언제 어떻게 하는지에 SSG, SSR이 다르다고 할 수 있다.
Next는 빌드 할 때, 이미 HTML문서를 가지고 있는 상태에서 서버로 요청이 들어올 때마다 알맞은 페이지를 반환 해 주는 pre-rendering을 한다.

이때, pre-rendering 형태가 2가지가 있다.


  1. Static Generation
  • 빌드 시, 각 페이지들에 대한 HTML문서를 생성해서 static 문서로 가지고 있다.
  • 각 페이지가 요청되면 이렇게 생성되어 있는 페이지를 전달한다.

  1. Server-side Rendering
  • 각 페이지의 요청이 있을 때마다 HTML문서를 생성해서 해당 페이지를 전달한다.

따라서 SSR은 SSG에 속해있다고 생각할 수 있다.

Server-side Rendering은 데이터가 수시로 변경될 때에 적합한 방식이고,
Static Generation은 정적인 페이지에 적합한 방식이다.

예를 들면, 게시판이나 댓글 페이지는 데이터가 수시로 변경되기 때문에 Server-side Rendering이 적합하다.
도움말, 이용안내, 카테고리 페이지 등 유저가 요청하기 전에 미리 페이지를 만들어놔도 상관없으면 정적페이지에는 Static Generation이 적합하다.

Next js?

React기반 SSR 프레임워크.
서버에서 pre-rendering을 통해 데이터와 html파일을 받아오기 때문에 SEO(Search Engine Optimization)에 최적화가 되어 있으며, 페이지 로딩 시간도 짧다.

React 기반 SSR 프레임워크로는 Gatsby, Next 가 있다.

수시로 데이터가 변경되는 페이지가 있다면 SSG+SSR 방식을 모두 제공하는 Next가 좀 더 적합하다고 한다.
정적인 페이지가 주를 이루고, 데이터가 자주 변경되지 않는다면 SSG 성능이 높은 Gatsby 프레임워크를 적용하는 것이 좋다고 한다.

getStaticProps

유저가 요청하기 전에 미리 페이지를 만들어놔도 상관없으면 정적페이지이면서 데이터는 외부에서 가져올 때 사용한다.

***index.js***

export default function Home({ list }) {
  return (
    <div>
      <Head>
        <title>Home|</title>
        <meta name="description" content="넥스트테스트프로젝트"></meta>
      </Head>

      <Header as="h3" style={{ paddingTop: 40 }}>
        베스트상품
      </Header>
      <Divider />
    </div>
  );
}

export async function getStaticProps() {
  const apiURL = "http://makeup-api.herokuapp.com/api/v1/products.json?brand=dior";
  const res = await Axios.get(apiURL);
  const data = res.data;

  return {
    props: {
      list: data,
    },
  };
}

getStaticPaths

다이나믹라우터에서도 정적페이지를 만들 수 있는 경우에 사용할 수 있다.
대부분 데이터를 같이 받아와야하기 때문에getStaticProps를 같이 사용해야 한다.
그러나 미리 만들어야 하는 페이지가 많다면 getServerSideProps로 호출 시마다 HTML을 생성하는 것이 빠르다.

const Post = ({ item }) => {
  const router = useRouter();
  console.log(router.isFallback);

  if (router.isFallback) {
    return (
      <div style={{ padding: "100px 0" }}>
        <Loader active inline="centered">
          Loading
        </Loader>
      </div>
    );
  }
  // fallback 이 true면 생성되어있지 않은 파일을 그려내는 동안 빈 화면이 보이기 때문에 Loading 컴포넌트 적용

  return (
    <>
      {item && (
        <>
          <Head>
            <title>{item.name}</title>
            <meta name="description" context={item.description}></meta>
          </Head>
          <Item item={item} />
        </>
      )}
    </>
  );
};

export default Post;

export async function getStaticPaths() {
  const apiURL = `http://makeup-api.herokuapp.com/api/v1/products/${id}.json`;
  const res = await Axios.get(apiURL);
  const data = res.data;

  return {
    paths: data.slice(0, 9).map((item) => ({
      params: {
        id: item.id.toString(),
      },
    })),
    fallback: true,
    
    // false면 미리 생성된 페이지가 아닌 경우에는 404페이지를 보낸다.
    // true는 처음에 props가 빈 상태로 그려지고, 백그라운드에서 정적파일로 HTML,JS 파일을 생성. 
    // NEXT는 pre-rendering 목록에 추가.
    // 그래서 두번째부터는 정적파일을 사용하는데, 새로고침하면 화면이 바로 띄워짐.
  };
}

export async function getStaticProps() {
  const apiURL = `http://makeup-api.herokuapp.com/api/v1/products/${id}.json`;
  const res = await Axios.get(apiURL);
  const data = res.data;

  return {
    props: {
      item: data,
    },
  };
}

getStaticProps 와 getStaticPath는 빌드 시 처음 가져오는 데이터이기 때문에 빈화면 없이 빠르게 화면이 렌더된다.

getServerSideProps

데이터가 수시로 업데이트 되는 페이지에 적용할 함수
유저의 요청에 따라 매 서버 호출 시마다 HTML 파일 생성하여 화면 렌더.
page 폴더에 router 경로(view)를 만들고, [ ] 로 감싼 js 파일 만들기
|-page
|--view
|---[id].js

const Post = ({ item }) => {
  return (
    <>
      {item && (
        <>
          <Head>
            <title>{item.name}</title>
            <meta name="description" context={item.description}></meta>
          </Head>
          <Item item={item} />
        </>
      )}
    </>
  );
};

export default Post;

export async function getServerSideProps() {
  const apiURL = `http://makeup-api.herokuapp.com/api/v1/products/${id}.json`;
  const res = await Axios.get(apiURL);
  const data = res.data;

  return {
    props: {
      item: data,
    },
  };
}

그동안 명확하게 알면서 사용하지 못했던 Next js 에 관련하여 코딩앙마의 영상을 통해 따라하면서 조금 더 깊게 공부하게 되었다.

만들어 놓은 프로젝트의 코드들을 보면서 리팩토링을 해야겠다.

profile
Whatever you want

0개의 댓글