Next.js를 배우기전에...!

thsoon·2020년 2월 20일
8

안녕하세요. thsoon입니다.
이번에 포스팅이란걸 처음 써보는 부족한 뉴비지만 차근차근 써보도록 하겠습니다.
포스팅을 시작하게 된 이유는 언제 한번 블로그를 만들고 싶은 생각이었기도 하고, 지금 하고 있는 프로젝트가 인원들이 서로 다른 분야의 기술을 가지고 있어, 기술 교류를 하고 있는데 친절한 설명이 필요하다 싶어 이번 기회에 글을 작성해봅니다.

이 시리즈는 Next.js의 공식 홈페이지의 문서를 베이스로 작성합니다.

Next.js란?

React에서 SPA의 Server Side Rendering(SSR)을 지원하기 위한 프레임워크입니다.
우선, SSR이 무엇인가 알아보기전에 Single Page Application(SPA)을 알아야겠죠?

SPA

Next를 찾아보신다는 것은 React를 하신 분들이 대다수라서 SPA를 아시겠지만, 간단하게 다시 말하자면 하나의 페이지로 모든 것을 조작하는 웹페이지라고 말할 수 있습니다.
View의 변경이 일어날 때, 전통적인 방식의 웹은 서버측에서 페이지를 다시 그려 줍니다.(Node의 ejs, Java의 JSP 등이 예시)
하지만 SPA는 서버의 필요한 데이터가 있을 때만 요청을 하고, 기존에 있던 JS 파일내의 DOM 조작 로직으로 부분적인 UI를 바꾸어줍니다.
즉, 사용자와의 인터렉션이 생겨 컨텐츠나 뷰가 바뀌어야하면 서버측에게 모든 파일을 다시 요청하는 것이 아닌, 필요한 데이터만을 가져와 기존에 가지고 있는 JS 파일로 DOM를 부분적으로 갱신해주기 때문에 네트워크 자원 소모를 획기적으로 줄여줍니다.

CSR과 SSR

하지만 방금 말한 라우팅 방식은 Client Side Rendering(CSR)입니다.
React에서 react-router-dom의 라우팅은 CSR을 제공하고 Next에서 제공하는 File System의 라우팅은 SSR을 제공합니다.
Client Side Rendering은 말 그대로 렌더링을 클라이언트(브라우저)에게 맡기는 것입니다. 일반적으로 서버에서 서빙하는 html엔 콘텐츠가 적은 상태로 도착하고 이어서 도착한 js파일들이 브라우저에서 콘텐츠를 그려주는 렌더링 방식입니다.
Server Side Rendering은 말 그대로 렌더링을 서버에서 작업하는 것입니다.
전통적인 웹페이지 제공 방식인 JSP나 Node의 Pug, ejs 등도 서버에서 렌더링하는 SSR 방식이지만 Next가 제공하는 SSR은 SPA를 지원해, 필요한 데이터만 부분적으로 요청받고 응답하는 방식입니다.

다음의 두번의 실습으로 CSR와 SSR의 차이를 간단하게 알아보겠습니다.

react-router-dom

CRA의 초기 기본 프로젝트 구성에서 react-router-dom을 npm install한 뒤, App.js를 다음 코드로 변경합니다.

import React from "react";
import { Link, BrowserRouter, Route } from "react-router-dom";
import A from "./components/A";
import B from "./components/B";

function App() {
  return (
    <BrowserRouter>
      <Link to="/">
        <h2>to A</h2>
      </Link>
      <Link to="/b">
        <h2>to B</h2>
      </Link>
      <Route exact path="/" component={A} />
      <Route path="/b" component={B} />
    </BrowserRouter>
  );
}

export default App;

그리고 src폴더에 components 폴더를 만든 뒤, 컴포넌트 A, B를 작성합니다.

// components/A.js
import React from "react";

const A = () => {
  return <div>A Component</div>;
};

export default A;

// components/B.js
import React from "react";

const B = () => {
  return <div>B Component</div>;
};

export default B;

npm start로 프로젝트 dev 서버를 실행 시키면

이런 화면이 나오는데, 여기서 to B 링크를 눌러서 B 페이지로 이동을 해도

네트워크 탭을 보시면 추가된 것이 없습니다. 이 뜻은 다른 페이지로 이동해도 서버에게 요청한 것이 없고 내부적인 JS로 B Component란 뷰를 그려준 것입니다.
B 페이지로 이동하기 위한 데이터는 첫 로딩 페이지인 A 페이지를 로딩할 때 가지고 있습니다.
즉, 처음 페이지를 로딩할 때 모든 페이지의 정보를 한 번에 다 가져옵니다.
하지만 "난 A 페이지만 접속할건데 B 페이지는 접속하지 않을거야"라는 사용자 입장에선 B 페이지 정보를 가져오는건 아무래도 처음 페이지 로딩을 더 느리게 만들고 네트워크 트래픽 자원을 더 소모하게 되죠
그래서 코드 스플리팅이란 기술을 적용하면 이를 해결합니다. Next.js에선 이것을 적용하기 쉽게 만들어줍니다. 코드 스플리팅에 대해선 추후에 포스팅을 하겠습니다.
또한, Postman으로 페이지 데이터를 가져오겠습니다.

컴포넌트 데이터가 없는 것을 볼 수 있습니다. 해당 페이지를 브라우저에 접속하면 A Component란 데이터가 뷰에 표시가 되는데 말이죠.
이런 결과가 발생한 이유는 CSR의 작동 원리는 빈 html 파일을 가져온 뒤, <div id="root"></div> 아래에 있는 script 파일들을 불러와서 렌더링을 하기 때문입니다.
즉, 브라우저에서 빈 index.html 로딩 -> script 파일들 로딩 -> script 로직에 따라 렌더링을 해줍니다.
이는 Search Engine Optimization(SEO)면에서 타격이 큽니다.
간단하게 말하면 몇 포털 사이트를 제외하면 웹 봇이 똑똑하지 않아서 js가 브라우저에 렌더링하는 데이터 없이 빈 index.html의 데이터를 참조하는 일이 많아지기 때문에 포털 검색에 자신의 웹페이지가 노출될 일이 현저히 줄어들게 됩니다.

next

Next.js 환경에선 위의 react-router-dom 실습과 비슷하게 환경을 구축합니다.
Next는 create-react-app 환경없이 자체적으로 webpack을 지원하기 때문에 빈 프로젝트부터 시작하기 편리합니다.
실습에 필요한 정보는 추후에 알아볼 것이므로 지금은 따라만 해보고 결과를 보면서 위의 실습 결과와 어떤 차이가 있는지 알면 좋을 것 같습니다.

프로젝트 구성

  1. 빈 디렉토리에서 npm init
  2. react, react-dom, next 모듈을 install
  3. package.json의 스크립트에 "dev": "next" 를 추가
  4. src, src/pages 디렉토리 생성
  5. src/pages엔 _app.js, b.js, index.js 파일 생성
  6. src/components 디렉토리를 생성하고 그 안에 AppLayout.js 파일 생성

코드

  1. src/pages/index.js
const IndexPage = () => {
  return <div>A component</div>;
};
export default IndexPage;
  1. src/pages/b.js
const B = () => {
  return <div>B component</div>;
};

export default B;
  1. src/pages/_app.js
import AppLayout from "../components/AppLayout";

const App = ({ Component }) => {
  return (
    <>
      <AppLayout />
      <Component />
    </>
  );
};

export default App;
  1. src/components/AppLayout.js
import Link from "next/link";

const AppLayout = () => {
  return (
    <>
      <Link href="/">
        <a>
          <h2>to A</h2>
        </a>
      </Link>
      <Link href="/b">
        <a>
          <h2>to B</h2>
        </a>
      </Link>
    </>
  );
};

export default AppLayout;

실행 결과

코드를 작성한 뒤, npm run dev를 실행하면

아까 실습과 같은 화면이 나옵니다. 여기서 똑같이 to B 링크를 누르게 되면

네트워크 탭에 B 페이지에 대한 데이터를 가져오는 것을 볼 수 있습니다.
to B 링크를 계속 누르게 되면 처음 클릭 때만 b.js를 가져오고 웹팩이 렌더링을 지시하는 데이터만 가져오게 됩니다.
그 이유는 b.js는 브라우저에서 캐싱되었기 때문이고, 페이지 전환때마다 서버에게 요청해 렌더링 정보를 받아 View를 갱신하는 것입니다.
그리고 Postman으로 페이지 데이터를 가져와보겠습니다.

이번엔 react-router-dom 실습때와 다르게 페이지의 콘텐츠 데이터도 같이 따라온 것을 볼 수 있습니다.
이는 react-router-dom과 next의 차이가 아닌, SSR 세팅을 하지 않는 React 환경과 SSR 환경을 제공해주는 Next의 차이라고 볼 수 있습니다.
그 덕분에 웹 봇 입장에서 좀 더 정확하게 웹 콘텐츠를 가져갈 수 있어 SEO면에서 장점을 취할 수 있습니다.

정리

  • Next는 Server Side Rendering을 제공하는 SPA 프레임 워크이다.
  • 코드 스플리팅 적용이 편리해 현재 필요한 페이지 정보만 제공할 수 있다.
  • 서버에서 콘텐츠를 렌더링하고 웹 페이지를 클라이언트에게 서빙하기 때문에 검색 엔진 최적화에 효율적이다.
  • 코드 스플리팅이 안된 CSR은 첫 로딩시에 모든 페이지 정보를 가져와 첫 로딩 속도와 네트워크 자원에서 비효율적이지만 Next는 코드 스플리팅과 필요한 페이지 정보만 그 때마다 가져오기 때문에 첫 로딩 속도가 빨라 UX면에서 좋고 네트워크 자원 소모가 보다 효율적이다.

다음 포스팅은 Next의 기본 프로젝트 구조와 Component의 Style 적용에 대해 다루겠습니다.

profile
바닥부터 쌓아가는 FE 개발자

0개의 댓글