IT/React & Next.js

[IT/Next.js] Next.js의 SSR 구현

땅일단 2024. 7. 28. 00:26

위 강의를 참고했습니다.

 

SSR과 CSR에 대해서는 아래 포스트를 참고해주세요.

 

[IT] SSR과 CSR의 차이점

프론트엔드 개념 중 많이 헷갈리는 SSR(Server Side Rendering)과 CSR(Client Side Rendering)에 대해 알아보겠습니다. SSR 일반적으로 MPA(Multi Page Application)에서 사용합니다. MPA는 각 페이지마다 파일이 존재하

doringri.tistory.com

 

- Next.js에서는 CSR으로도 구현이 가능하지만 SSR을 권장하고 있음.

- 퍼포먼스가 더 좋고, SEO에도 좋기 때문. (검색 엔진이나 카카오톡 등에서의 링크 공유 시 내용 표출되는 것)

- 마케팅 페이지, 블로그 게시물, 제품 리스트, 도움말 페이지 등에서 사용하면 좋다고 한다. (SEO나 초기 페이지 로딩 속도가 중요한 페이지)

- 반면 사용자와의 상호작용이 중요하거나 MQTT같은 실시간 구독 페이지는 CSR이 더 권장된다.

- getStaticProps, getStaticPaths, getServerSideProps 를 사용하여 구현

- 매 요청마다 html을 생성하여 페이지가 항상 최신 상태를 유지한다.

- 예시 코드 (블로그 게시물)

import Axios from "axios"

const Post = ({item}) => {
    return (
        <>
            {
                item && (
                    <div>
                        <h1>
                            {item.name}
                        </h1>
                        <div>
                            {item.description)
                        </div>
                    </div>
                )
            }
        </>
    );
};

export default Post;

export async function getServerSideProps(context) {
    const id = context.params.id;
    const res = await Axios.get(`http://localhost:8080/${id}`);
    const data = res.data;
    
    return {
        props: {
            item: data
        }
    }
}

위 예시 코드에서는 getServerSideProps라는 함수를 통해 SSR을 구현하고 있다.

이 함수의 파라미터인 context라는 객체에서는 페이지를 요청했을 때의 다양한 정보를 담고 있어서 저런 식으로 주소 파라미터를 가져오는 것이 가능하다.

 

API 서버에서 받아온 리소스를 item으로 Post에 넘기고, 미리 만들어둔 정적 데이터(html)에 그 리소스를 표시한다.

 

(+)

getStaticProps정적 페이지를 생성할 때 쓰는 함수로 위의 getServerSideProps와 형태는 동일하다. 하지만 getServerSideProps는 "req" 미들웨어를 통해 api 요청(새로고침) 시마다 새로운 HTML을 렌더링하지만 getStaticProps는 동일한 HTML을 제공한다. 성능 면에서 getServerSideProps보다 뛰어나므로 내용을 동적으로 수정할 일이 없다면 보통은 getStaticProps를 쓰는 것이 더 권장된다.

 

getStaticPaths는 getStaticProps의 정적인 경로를 정의할 때 쓰는 함수이다. 사용법은 아래와 같다.

export async function getStaticPaths() {
  const res = await fetch("http://localhost:8080/posts");
  const posts = await res.json();
  
  // post의 개수만큼 경로 할당
  const paths = posts.map((post) => ({
    params: { id: post.id.toString() },
  }));
  
  // fallback: false는 이외의 페이지에 404 페이지 처리
  return {paths, fallback: false};
}