SSR과 CSR 혼합해서 사용해보기🛠️

임동현·2022년 4월 22일
5
post-thumbnail

최근에 프로젝트를 진행하다가 막히는게 있어서 도움을 받으려고 졸업하신 선배님이 일하시는 회사에 들렸었습니다...! 가서 리덕스 툴킷, 비동기 통신 라이브러리(SWR, React-Query),Next 등 여러 가지 기술들에 대해 얘기를 해봤습니다. 이중에서도 Next에 대해 제가 궁금한게 많아서 여러 질문들을 했는데, 선배님이 SSR에 대해 중요한 정보를 하나 알려주셨습니다. 바로 Next에서 CSR과 SSR을 같이 사용하면 UX적으로 최적화 할 수 있다는 것입니다...! 많이 어렵게 들릴 수도 있지만 차근차근 설명해 보겠습니다..

먼저 SSR과 CSR을 알아야 하는데요 자세한 포스트는 여기로 들어가서 보시고, 간단하게 설명하겠습니다.

SSR

간단하게 SSR은 빌드 타임에서 API호출을 하여 미리 데이터를 패치한 후 빌드가 다 되면 먼저 패치한 데이터를 바로 보여주는 방식으로 UX적으로 사용자가 흰화면을 보지않고 바로 내용을 볼 수 있습니다.

CSR


CSR은 원래 리액트 작업 하던대로 모든 빌드가 끝난 후에 한번에 모든 자바스크립트 코드를 다운로드 하여 페이지간 이동할때 로딩시간이 적게 해줍니다.

이렇게 SSR CSR 각각의 rendering 방식들은 장단점이 있는데요,
만약 모든 rendering을 SSR로 한다면 어떨까요?

빌드 타임에서 API호출을 하여 미리 데이터를 패치한 후 빌드가 다 되면 먼저 패치한 데이터를 바로 보여주는 방식

이 방식을 통해 사용자는 맨처음 들어올때는 흰화면을 보지 않고 바로 내용을 볼 수 있지만, 다른 페이지를 이동할 때마다 서버에서 API호출을 하게 되어 API 호출이 끝나기 전까지는 페이지를 이동하지 못하고 묶여있어야 합니다. 이부분이 SSR 방식의 단점입니다.

그러면 만약 모든 rendering을 CSR로 한다면 어떨까요?

모든 빌드가 끝난 후에 한번에 API 호출하는 방식

이 방식을 통해 사용자는 맨처음 흰화면을 봐야된다는 단점이 있지만, 페이지마다 로딩시간이 줄어든다는 장점이 있습니다.

자, 두 방법을 비교했을 때 서로의 단점을 보완할 수 있을 것 같지 않나요? 코드로 한번 설명해보겠습니다.

TestPage.getInitialProps = async () => {
  const isServer = typeof window === "undefined";

  const api = async () => {
    try {
      const data = await axios.get("/test");
      return data;
    } catch (error) {
      return null;
    }
  };

  if (isServer) {
    const data = await api(); 

    return { isClient: false, ssrData: data };
  } else {
    return { isClient: true, ssrData: null };
  }
};

먼저 Next에서 ssr을 할려면 getServerSideProps, getStaticProps, getInitialProps 와 같은 비동기 함수를 적어주면 되는데요, 여기서 isServer 에 따라 ssr 처리, csr 처리를 해줍니다.

window 객체는 csr 상태일때만 생기고 ssr 상태일때는 undefined 상태입니다. 그래서 window를 통해서 csr인지 ssr인지를 구분해줍니다.

ssr일때는 getInitialProps 안에서 api통신을 하여 값을 리턴해줍니다.

type Props = {
  ssrData: any;
  isClient: boolean;
};

const TestPage: NextPage<Props> = ({ ssrData, isClient }) => {
  const [data, setData] = useState(null);

  const api = async () => {
    try {
      const { data } = await axios.get("/test");
      setData(data);
    } catch (error) {
      setData(null);
    }
  };

  useEffect(() => {
    if (isClient) {
      api();
    }
  }, [isClient]);

  return <div>{isClient ? <div>{ssrData}</div> : <div>{data}</div>} </div>;
};

페이지에서는 ssr함수가 리턴해준 값에 따라 처리를 해줍니다. isClient라는 값을 받아 true일때만 useEffect(csr)에서 비동기 함수를 실행 해줍니다.

이런식으로 하게 되면 csr과 ssr을 혼합하여 사용할 수 있습니다..!

마치며⭐

처음 선배님께서는 원리만 알려주셔서(아마도 저의 성장을 위해서겠죠?) 엄청난 구글링을 했습니다... 하지만 이렇게 성공했으니 뿌듯한 느낌이 듭니다...ㅠㅠ 하지만 위에 올린 방법도 아직 문제점(똑같은 api함수를 2개를 만들어야 한다는 점)이 있습니다. 해결하기 위해서 열심히 next를 파야겠습니다... 모두 즐넥하세요!

참고

Dynamic Route CSR, SSR 요청 구분 하기!
sh031224/Slog

profile
깊게 알기 위해 노력하는 주니어 프론트엔드 개발자입니다 😎

0개의 댓글