React.lazy 및 Suspense를 사용한 코드 분할

사용자에게 필요한 것보다 많은 코드를 제공할 필요가 없으므로 이러한 일이 발생하지 않도록 번들을 분할하세요.

React.lazy 메서드를 사용하면 동적 가져오기를 사용하여 구성요소 수준을 조정할 수 있습니다

import React, { lazy } from 'react';

const AvatarComponent = lazy(() => import('./AvatarComponent'));

const DetailsComponent = () => (
  <div>
    <AvatarComponent />
  </div>
)

이것이 왜 유용할까요?

대규모 React 애플리케이션은 일반적으로 많은 구성요소, 유틸리티 메서드, 서드 파티 라이브러리 등에서 사용할 수 있습니다. 로드하려고 하지 않으면 필요할 때만 애플리케이션의 여러 부분으로 구성된 컨테이너 이미지를 자바스크립트 번들은 사용자가 첫 번째 페이지입니다. 이 경우 페이지 성능에 상당한 영향을 줄 수 있습니다.

React.lazy 함수는 별도의 자바스크립트 청크로 분할할 수 있습니다. 다음과 같은 작업을 할 수 있습니다. 그런 다음 Suspense 구성요소를 사용합니다.

서스펜스

사용자에게 대량의 JavaScript 페이로드를 전달할 때 발생하는 문제는 특히 성능이 낮은 기기에서 페이지 로드를 완료하는 데 걸리는 시간 네트워크 연결이 있습니다 코드 분할과 지연 로드가 매우 유용합니다.

하지만 광고가 종료되고 광고가 실행될 때 사용자가 코드 분할 구성 요소는 네트워크를 통해 가져오므로 유용한 로드 상태를 표시합니다. Suspense와 함께 React.lazy 사용 이 문제를 해결하는 데 도움이 됩니다.

import React, { lazy, Suspense } from 'react';

const AvatarComponent = lazy(() => import('./AvatarComponent'));

const renderLoader = () => <p>Loading</p>;

const DetailsComponent = () => (
  <Suspense fallback={renderLoader()}>
    <AvatarComponent />
  </Suspense>
)

Suspense는 모든 React를 표시할 수 있는 fallback 구성요소를 허용합니다. 구성요소를 로드 상태로 유지합니다. 다음 예는 작동 방식을 보여줍니다. 아바타는 버튼을 클릭할 때만 렌더링되며, 여기서 정지된 AvatarComponent에 필요한 코드를 가져오도록 생성됩니다. 그동안은 대체 로드 구성요소가 표시됩니다.

여기서 AvatarComponent를 구성하는 코드는 다음과 같이 작습니다. 로딩 스피너가 짧은 시간 동안만 표시되는 이유 크게 로드하는 데 시간이 훨씬 더 오래 걸릴 수 있으며, 특히 손상시킬 수 있습니다.

작동 방식을 더 잘 보여주는 방법:

  • 사이트를 미리 보려면 앱 보기를 누릅니다. 그런 다음 전체 화면 전체 화면입니다.
  • `Control+Shift+J` (또는 Mac의 경우 `Command+Option+J`)를 눌러 DevTools를 엽니다.
  • 네트워크 탭을 클릭합니다.
  • 제한 드롭다운을 클릭합니다. 이 드롭다운은 기본적으로 제한 없음으로 설정되어 있습니다. 빠른 3G를 선택합니다.
  • 앱에서 Click Me 버튼을 클릭합니다.

로딩 표시기가 더 오래 표시됩니다. 인코더-디코더에 삽입된 AvatarComponent를 별도의 청크로 가져옵니다.

<ph type="x-smartling-placeholder">
</ph> 다운로드 중인 하나의 chunk.js 파일을 보여주는 DevTools 네트워크 패널

여러 구성요소 정지

Suspense의 또 다른 기능은 여러 인스턴스를 모든 구성요소가 지연 로드되더라도 로드를 막을 수 있습니다.

예를 들면 다음과 같습니다.

import React, { lazy, Suspense } from 'react';

const AvatarComponent = lazy(() => import('./AvatarComponent'));
const InfoComponent = lazy(() => import('./InfoComponent'));
const MoreInfoComponent = lazy(() => import('./MoreInfoComponent'));

const renderLoader = () => <p>Loading</p>;

const DetailsComponent = () => (
  <Suspense fallback={renderLoader()}>
    <AvatarComponent />
    <InfoComponent />
    <MoreInfoComponent />
  </Suspense>
)

이는 여러 구성요소의 렌더링을 지연시키는 매우 유용한 단일 로드 상태만 표시합니다. 모든 구성요소가 완료되면 사용자는 그 모든 것을 동시에 볼 수 있습니다.

다음을 삽입하여 이를 확인할 수 있습니다.

그렇지 않으면 시차 로드, 또는 차례로 로드되는 UI의 여러 부분이 있고 각 부분에는 고유한 로드 표시기가 나타납니다. 이로 인해 사용자 환경이 거슬리는 느낌을 줄 수 있습니다.

로드 실패 처리

Suspense를 사용하면 네트워크가 작동하는 동안 임시 로드 상태를 표시할 수 있습니다. 요청은 내부에서 이루어집니다 하지만 이러한 네트워크 요청이 여러 시간 동안 뭔가? 오프라인 상태이거나 웹 앱에서 버전이 지정된 URL 지연 로드 서버 재배포 후 더 이상 사용할 수 없는 애플리케이션이 있습니다.

React에는 이러한 유형의 로드를 적절하게 처리하기 위한 표준 패턴이 있습니다. 실패: 오류 경계 사용 문서에 설명된 대로 모든 React 구성요소는 React 구성 요소가 둘 다) 수명 주기 메서드 static getDerivedStateFromError() 또는 componentDidCatch()입니다.

지연 로드 실패를 감지하고 처리하려면 Suspense를 래핑하면 됩니다. 오류 경계 역할을 하는 상위 구성요소가 있는 구성요소. 내부 오류 경계의 render() 메서드가 있는 경우 하위 요소를 있는 그대로 렌더링할 수 있습니다. 오류 발생 시 커스텀 오류 메시지를 렌더링합니다.

import React, { lazy, Suspense } from 'react';

const AvatarComponent = lazy(() => import('./AvatarComponent'));
const InfoComponent = lazy(() => import('./InfoComponent'));
const MoreInfoComponent = lazy(() => import('./MoreInfoComponent'));

const renderLoader = () => <p>Loading</p>;

class ErrorBoundary extends React.Component {
  constructor(props) {
    super(props);
    this.state = {hasError: false};
  }

  static getDerivedStateFromError(error) {
    return {hasError: true};
  }

  render() {
    if (this.state.hasError) {
      return <p>Loading failed! Please reload.</p>;
    }

    return this.props.children;
  }
}

const DetailsComponent = () => (
  <ErrorBoundary>
    <Suspense fallback={renderLoader()}>
      <AvatarComponent />
      <InfoComponent />
      <MoreInfoComponent />
    </Suspense>
  </ErrorBoundary>
)

결론

React에 코드 분할 적용을 어디에서 시작해야 할지 잘 모르겠다면 다음 단계를 따르세요.

  1. 경로 수준에서 시작합니다. 경로는 목적지를 식별하는 가장 간단한 방법입니다. 애플리케이션을 분할할 수 있습니다. 이 React 문서 Suspense와(과) 함께 사용하는 방법 react-router
  2. 사이트에서만 렌더링되는 대형 구성요소를 모두 확인합니다. 특정 사용자 상호작용 (예: 버튼 클릭) 분할 구성요소는 JavaScript 페이로드를 최소화합니다.
  3. 화면 밖이고 화면에 중요하지 않은 것은 분할하는 것이 좋습니다. 있습니다.