본문 바로가기
Frontend/ReactJS(완)

React - 19장 : 코드 스플리팅(완)

by VictorMeredith 2023. 3. 2.

<리액트를 다루는 기술>

React - 1장 : React 이해

React - 2장 : JSX

React - 3장 : 컴포넌트

React - 4장 : 이벤트 핸들링

React - 5장 : ref. DOM에 이름 달기 

React - 6장 : 컴포넌트 반복
React - 7장 : 컴포넌트의 LifeCycle
React - 8장 : React Hooks 총정리

React - 9장 : 컴포넌트의 스타일링

React - 10장 : 빠르게 TODO앱 실습

React - 11장 : 컴포넌트 성능 최적화

React - 12장 :  immer를 사용하여 더 쉽게 불변성 유지하기

React - 13장 : 리액트 라우터로 SPA 개발하기

React - 14장 : 뉴스 뷰어 예제프로젝트

React - 15장 : ContextAPI

React - 16장 : 리덕스 라이브러리의 이해

React - 17장 : 리덕스 실습

React - 18장 : 리덕스 미들웨어를 통한 비동기 작업 관리

React - 19장 : 코드 스플리팅(현재)


리액트프로젝트를 빌드할때 보통 웹팩이 번들링을 해준다. 이 과정에서 모든 파일을 압축해서 주석, 공백 등을 지우기도 하고 바벨을 사용해서 다양한 브라우저에 대응하기도 하며, 이미지같은 정적 파일의 경로를 세팅해주기도 한다.

CRA로 프로젝트를 빌드할 경우, 최소 두 개 이상의 JS 파일이 생성된다. 기본 웹팩 설정에는 SplitChunks라는 기능이 적용되어 캐싱의 효과를 누릴 수 있게 해준다.

npx create-react-app splitting-sample
cd splitting-sample
npm run build

- 빌드해보자.

- build/static 폴더에 빌드가 되었다.

hash값이 포함된 js파일 여러개

- 앞에 787.273c5611 이런 hash값을 통해 브라우저가 새로 파일을 받아야 할지 말지를 알 수 있다.

- 해시가 앞에 붙은 파일은 node_modules에서 불러운 라이브리 관련 코드가 들어있고, main으로 시작하는 파일에는 직접 프로젝트에 작성하는 App 같은 컴포넌트에 관한 코드가 들어있다.

- SplitChunks라는 웹팩 기능을 통해 해시파일명js 는 바뀌지 않고 main~.js파일만 바뀌는데, 이렇게 파일을 분리하는 작업을 코드 스플리팅이라고 한다.

- 하지만 리액트에 별도로 설정하지 않으면 모든 컴포넌트의 코드가 모두 한 파일(main어쩌고)에 담기게 된다. 

- 규모가 커지게되면 당연히 파일이 커지고 로딩이 오래걸리므로 구려진다.

- 이런 문제를 해결하기 위해서 코드 비동기로딩을 사용한다. 이 또한 코드 스플리팅의 방법 중 하나이다.

 

19-1. JS 함수 비동기 로딩

- 일반 자바스크립트 함수 스플리팅 해보기

 

src/notify.js

export default function notify(){
    alert('하이염')
}

 

App.js

import notify from "./notify";

function App() {

  const onClick = ()=>{
    notify();
  }

  return (
    <div className="App">
      <button onClick={onClick}>하이욤?</button>
    </div>
  );
}

export default App;

- 하이욤 버튼을 누르면 하이염이 alert로 뜨게 해놨다.

- 이렇게 하고 빌드하면 notify 코드가 main 파일 안에 들어가게 된다.

- 하지만 import를 상단에서 하지 않고 import()함수 형태로 메서드 안에서 사용하면 파일을 따로 분리시켜 저장한다.

- 그러면 실제 함수가 필요한 지점에서 파일을 불러와서 함수를 사용한다.

- 수정해보자

 

App.js

function App() {

  const onClick = ()=>{
    import('./notify').then((result)=>{result.default()})
  }

  return (
    <div className="App">
      <button onClick={onClick}>하이욤?</button>
    </div>
  );
}

export default App;

- import 함수는 Promise객체를 반환한다. 그래서 .then을 쓸 수 있다.

- import 함수 문법은 dynamic import라는 문법으로, 웹팩에서 기본 지원한다.

처음 로딩했을 때 네트워크 탭에서 확인할 수 있는 로딩 목록이다

- 버튼을 눌러보면

버튼을 눌러서야 src_notify_js.chunk.js 가 로드 되었다.

 

19-2. React.lazy와 Suspense 를 통한 컴포넌트 코드 스플리팅

- 코드 스플리팅을 위해 리액트 내장 기능인 React.lazy와 Suspense가 있다.

const SplitMe = React.lazy(()=>{ import('./SplitMe') })

- SplitMe 컴포넌트를 스플리팅하는 예시코드이다.

- Suspense 컴포넌트를 사용하면 코드 스플리팅 된 컴포넌트를 로딩하도록 발동시킬 수 있고, 로딩 중 UI를 설정할 수 있다.

<Suspense fallback={<div>로딩중</div>}>
  <SplitMe/>
</Suspense>

- react 18 부터는 Suspense를 이용한 SSR 아키텍쳐 구축이 가능해졌다. 

 

 

- 이렇게 'React를 다루는 기술 개정판' 에 대한 복습 및 포스팅이 끝났다.

- 이제는 실제 MERN 프로젝트를 진행하고, 새로 나온 기술들을 익히며 포스팅한다.

- 리액트는 라이브러리이고 html css js 를 쉽고 빠르게 효율적으로 만들기 위한 도구일 뿐이지, 대단한 슈퍼 웹기술 같은 것이 아니다.

- 웹페이지의 근본은 html css js 이고, 프로그래밍의 근본은 CS/알고리즘이다. 리액트/뷰/익스프레스 등의 프레임워크 기술이 어떠한 고민들에 의해서 탄생했는지, 왜 그 스택을 사용하는지에 대한 고민도 함께 하다보면 현명한 개발자가 될 수 있다.

댓글