[React] Next.js / 서버사이드 렌더링 (Server-side Rendering/SSR/Dynamic Rendering)

glow_soon·2022년 4월 27일
1

React

목록 보기
45/52

Next.js 는 모든 페이지를 사전에 렌더링
pre-rendering: 미리 html 파일들을 만들어 놓는것

더 좋은 퍼포먼스와 검색엔진 최적화(SEO)를 자랑한다.

Pre-rendering에는 두가지형태가 있음

  1. 정적 생성
  2. Server Side Rendering (SSR, Dynamic Rendering)

두가지의 차이점은 언제 html 파일을 생성하는지에 갈린다.

정적 생성

  • 프로젝트가 빌드하는 시점에 html 파일들이 생성
  • 모든 요청에 그 파일들을 재사용 (파일들을 쭉 만들어놓고 호출이 들어올때마다 재사용하는 방식)
  • 퍼포먼스 이유로, next.js는 정적 생성을 권고
  • 정적 생성된 페이지들은 CDN에 캐시

    CDN이란
    Content Delivery Network의 약자
    지리적 제약 없이 전 세계 사용자에게 빠르고 안전하게 콘텐츠를 전송할 수 있는 콘텐츠 전송 기술을 의미
    CDN은 서버와 사용자 사이의 물리적인 거리를 줄여 콘텐츠 로딩에 소요되는 시간을 최소화합니다.
    CDN은 각 지역에 캐시 서버(PoP, Points of presence)를 분산 배치해, 근접한 사용자의 요청에 원본 서버가 아닌 캐시 서버가 콘텐츠를 전달
    출처: https://library.gabia.com/contents/infrahosting/8985/

  • getStaticProps / getStaticPaths

서버사이드 렌더링(Server-side Rendering)

  • 매 요청마다 html을 생성
  • 항상 최신 상태 유지
  • getServerSideProps

이둘의 사용은 어떻게 구분할까?

유저가 요청하기전 미리 페이지를 만들어놔도 상관없으면 정적 생성 (회사 소개 페이지,,,도움말,,,등등)
하지만 쇼핑몰 상세페이지등의 서비스들은 상품의 정보가 자주 바뀌는데 화면을 띄우기전에 데이터가 있어야 상품의 정보를 보여줄수 있을것, 따라서 SSR이 좋은 방식

// [id].js
const Post = ({ item }) => {
  /*const router = useRouter();
  const { id } = router.query;
  const [item, setItem] = useState({});
  const API_URL = `http://makeup-api.herokuapp.com/api/v1/products/${id}.json`;
  const [loading, setLoading] = useState(true);
  useEffect(() => {
    if (id && id > 0) {
      axios.get(API_URL).then((res) => {
        console.log(res.data);
        setItem(res.data);
        setLoading(false);
      });
    }
  }, [id]);*/

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

export default Post;

export async function getServerSideProps(context) {
  const id = context.params.id;
  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,
    },
  };
}

getServerSideProps()를 통해 SSR 방식을 사용한다. 이 함수안에 파라미터는 여러 정보를 받아올수 있음. 지금은 url상의 해당 상품의 아이디를 받아오는 상태이다.
axios로 받아 온 res.data를 data 변수에 저장하고 props로 보내 줄 수있다. Post 컴포넌트에 보내 주었고, 해당 정보를 잘 렌더링 해주기만 하면 된다.

해당 페이지의 소스를 보면 상품의 설명들이 그 전과는 다르게 들어가 있다. 검색엔진이나 공유할때 이런 정보를 사용 가능할것이다. 또한 항상 최신상태를 유지 (but, 요청이 늘어나 퍼포먼스는 떨어지는 단점)


more next/router

현재 메뉴바는 active하게 움직이지 않는 상태이다

// Gnb.js
import { Menu } from "semantic-ui-react";
import { useRouter } from "next/router";
export default function Gnb() {
  const router = useRouter();
  let activeItem;
  
 // 시멘틱 ui active 컨트롤 조건문
  if (router.pathname === "/") {
    activeItem = "home";
  } else if (router.pathname === "/about") {
    activeItem = "about";
  }

  function goLink(e, data) {
    if (data.name === "home") {
      router.push("/");
    } else if (data.name == "about") {
      router.push("/about");
    }
  }
  return (
    <Menu inverted>
      <Menu.Item name="home" active={activeItem === "home"} onClick={goLink} />
      <Menu.Item
        name="about"
        active={activeItem === "about"}
        onClick={goLink}
      />
    </Menu>
  );
}

goLink 함수는 시멘틱 UI에서 제공하는 함수로 시멘틱 UI내에서 속성으로 설정한 name에 따라 작동한다.
Home버튼을 눌렀다면 data.name=="home"이기 때문에 useRouter()를 활용, push로 해당 페이지로 이동 시켜준다.

상단의 조건문은 버튼이 눌린 효과를 주기위한 조건문이다.
userRouter로 선언한 router변수는 많은 정보를 담고 있고 콘솔에서 확인해보았다.
이중에 해당 path의 이름을 저장하고 있는 pathname 변수를 사용해서 시멘틱 UI의 active 속성을 관리해 주었다.

잘 적용 되었다.

코딩앙마님 유튜브 https://www.youtube.com/channel/UCxft4RZ8lrK_BdPNz8NOP7Q 에서 공부한 내용을 기록한 글입니다

profile
나는야 코린이

0개의 댓글