React.lazy 및 코드 분할

코드 분할

React 프로젝트가 완성되어 사용자에게 제공되면 빌드 작업을 통해 배포해야 합니다.

빌드 작업을 통해 JavaScript 파일에서 불필요한 주석과 공백을 제거하여

파일 크기 최소화

브라우저에서 JSX 구문이나 최신 JavaScript 구문이 원활하게 실행될 수 있도록

나는 종종 코드의 트랜스 파일도 수행합니다.

프로젝트에 이미지와 같은 정적 파일이 있는 경우 해당 파일의 경로도 설정해주세요!

이러한 작업은 Create React-app에서 webpack에 의해 처리됩니다.

webpack에서 별도의 설정을 하지 않으면 해당 프로젝트에서 사용 중인 모든 자바스크립트 파일이

하나의 파일로 병합되고 모든 CSS 파일도 하나의 파일로 병합됩니다.

CRA로 프로젝트를 빌드할 때 최소한 두 개의 JavaScript 파일이 생성됩니다.

CRA의 기본 웹팩 구성에는 SplitChunks라는 기능이 적용되어 있습니다.

node_modules에서 로드된 파일, 일정 크기 이상의 파일, 여러 파일 간에 공유되는 파일

등을 자동으로 분리하여 캐싱의 효과를 누릴 수 있도록 도와줍니다.

그러나 splitChunks에는 효율적인 캐싱 효과만 있습니다!

따라서 React 프로젝트에서 별도로 설정하지 않는다면,

SPA를 개발하는 상황에서 A페이지만 랜더링이 가능한 상황에서

모든 구성 요소가 하나의 파일에 저장되므로 모든 페이지가 로드됩니다.

이로 인해 사용자 경험이 저하됩니다.

이 문제를 해결하기 위해 코드 비동기 로딩이라는 방법을 채택할 수 있습니다.

코드 비동기 로딩을 통해 JavaScript 함수, 개체 및 구성 요소를 로드합니다.

필요할 때 불러서 사용할 수 있습니다.

연습을 통해 코드 분할을 해봅시다.


동적 가져오기

src/notify.js

export default function notify() {
  alert('안녕하세요');
}

간단한 모듈을 만들어 봅시다.

실행시 경고창이 뜨는 함수를 작성해서 내보냈습니다.

/src/app.js

import logo from './logo.svg';
import './App.css';
import notify from './notify';

function App() {
  const onClick = () => {
    notify();
  };
  return (
    <div className="App">
      <p onClick={onClick}> hello react</p>
    </div>
  );
}

export default App;

App.js에서는 notify를 호출해서 사용했습니다.

이렇게 정상적으로 코드를 작성하고 빌드하면 알림 코드가 메인 파일 내부로 들어가게 됩니다.

단, 위와 같이 상단에 import 하지 않고

메서드에서 동적 가져오기 구문을 사용하면 파일이 분리되어 저장됩니다.

동적 가져오기 구문은 다음과 같이 작성됩니다.

import('경로')

매우 간단합니다

https://ko.javascript.info/modules-dynamic-imports

모듈을 동적으로 가져오기

ko.javascript.info

위 링크에서 더 많은 정보를 확인하실 수 있습니다.

언뜻 보면 함수 호출처럼 보입니다.

super()와 같이 괄호를 사용하는 JavaScript의 구문이라고 합니다.

이러한 동적 가져오기 구문은 약속을 반환합니다.

따라서 then, catch, and finally 약속 후처리 방법을 사용하는 것도 가능합니다.

그렇다면 이전 코드를 이렇게 수정할 수 있습니다.

import logo from './logo.svg';
import './App.css';
import notify from './notify';

function App() {
  const onClick = () => {
    import('./notify').then((result) => result.default());
  };
  return (
    <div className="App">
      <p onClick={onClick}> hello react</p>
    </div>
  );
}

export default App;

이와 같이 동적 가져오기를 사용하여 모듈을 로드할 때 모듈에서 기본 구문을 통해 내보내는 것은 무엇입니까?

성공 결과의 기본값을 참조하여 사용해야 합니다.


React.lazy 및 코드 분할 1

그런 다음 빌드 명령을 사용하여 빌드하십시오.

동적 가져오기를 사용하기 전과 비교하여 더 많은 파일이 생성된 것을 확인할 수 있습니다.


React.lazy

이 코드 분할을 위해 React는 버전 16.6부터 내장 함수였습니다.

유틸리티 기능 React.lazy 및 컴포넌트 Suspense를 제공합니다.

React 16.6 이전 버전을 사용하려면 가져오기 기능을 통해 가져오신 후

구성 요소 자체를 상태에 넣어 구현해야 했습니다.

이제 유틸리티 기능을 통해 쉽게 구현할 수 있습니다.

React.lazy는 렌더링 시간에 컴포넌트를 비동기적으로 로드할 수 있게 해주는 유틸리티 함수입니다.

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

오 쉽지

동적 가져오기를 트리거하는 함수를 React.lazy에 대한 콜백으로 전달하면 완료됩니다.

이 splitMe를 사용하려면 Suspense라는 내장 React 구성 요소를 사용할 수 있습니다.

Suspense는 코드 분할 구성 요소를 로드하도록 트리거할 수 있는 React 내장 구성 요소입니다.


로딩이 완료되지 않았을 때 표시되는 UI 설정도 지원합니다!

Suspense를 사용하는 방법도 contextAPI나 Redux에 익숙하다면 매우 쉽게 받아들일 수 있습니다.

import { suspense } from 'react'

(...)

<Suspense fallback={<div> loading... </div>}>
  <SplitMe />
</Suspense>

Suspense의 폴백 속성을 사용하면 로드 중에 표시할 jsx를 지정할 수 있습니다!

import logo from './logo.svg';
import './App.css';
import notify from './notify';
import React, { useState, Suspense } from 'react';
const SplitMe = React.lazy(() => import('./SplitMe'));

function App() {
  const (visible, setVisible) = useState(false);
  const onClick = () => {
    setVisible(true);
  };
  return (
    <div className="App">
      <p onClick={onClick}> hello react</p>
      <Suspense fallback={<div>loading...</div>}>
        {visible && <SplitMe />}
      </Suspense>
    </div>
  );
}

export default App;

위와 같이 App.js를 구성합니다.

이 코드는 표시 상태가 true인 경우에만 SplitMe를 렌더링합니다.

SplitMe는 Reactrage를 통해 수입됩니다!

SplitMe는 간단한 구성 요소로 구성될 수 있습니다.

간단하게 이렇게 구성했습니다

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

export default SplitMe;

너무 간단합니다.


React.lazy 및 코드 분할 2

그런 다음 SplitMe를 렌더링해야 하는 상황을 설정하면

분할된 SplitMe가 호출되는 것을 확인할 수 있습니다.

짜증나


React.lazy 및 코드 분할 3

Network 탭에서 제가 Slow 3G로 설정한 부분이 보이시나요?

해당 부분을 통해 네트워크 속도를 조정할 수 있습니다.

로딩 화면이 잘 나오는지 확인하기 위해 네트워크 속도를 천천히 변경한 후

확인해보고 원래 설정으로 다시 변경하겠습니다.


엔딩

저는 단순히 React.lazy와 Suspense를 사용하여 연습했습니다.

다음으로 Loadable Components라는 라이브러리를 통해 연습해 보겠습니다.



React.lazy 및 코드 분할 4
가장 무서운 때는 이해한다고 생각할 때입니다.