React.lazy と Suspense によるコード分割

ユーザーに必要以上に多くのコードを配布する必要はありません。バンドルを分割して、このようなことがないようにします。

React.lazy メソッドを使用すると、React アプリケーションを 動的インポートを使用してコンポーネントレベルで データをインポートできます

import React, { lazy } from 'react';

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

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

なぜこれが有用なのでしょうか。

大規模な React アプリケーションは、通常、多くのコンポーネント、ユーティリティ、 メソッド、サードパーティ ライブラリが含まれます。読み込みを試行しない場合は、 アプリケーションの各部分を必要なときにのみ使用し、 ユーザーが JavaScript のバンドルを読み込むとすぐに、 表示されます。これは、ページのパフォーマンスに重大な影響を与える可能性があります。

React.lazy 関数は、組み込みのメカニズムを使用して、 JavaScript のチャンクに分割する必要がありました。Google Chat では 次に、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 を構成するコードは小さく、 読み込みスピナーが短時間しか表示されない理由拡大 コンポーネントの読み込みに時間がかかる ネットワーク接続を遮断します。

この仕組みをわかりやすく説明するために、

  • サイトをプレビューするには、[アプリを表示] を押します。[ 全画面表示 全画面表示
  • Ctrl+Shift+J キー(Mac の場合は Command+Option+J キー)を押して DevTools を開きます。
  • [ネットワーク] タブをクリックします。
  • デフォルトで [スロットリングなし] に設定されている [スロットリング] プルダウンをクリックします。[Fast 3G] を選択します。
  • アプリで [Click Me] ボタンをクリックします。

読み込みインジケーターの表示時間が長くなりました。前のスライドで紹介したすべてのコードが AvatarComponent が個別のチャンクとしてフェッチされます。

<ph type="x-smartling-placeholder">
</ph> ダウンロード中の 1 つの chunk.js ファイルが表示されている DevTools ネットワーク パネル

複数のコンポーネントの一時停止

Suspense のもう 1 つの機能として、複数の VM を一時停止できます。 (すべてのコンポーネントが遅延読み込みされている場合でも)、読み込みが行われなくなります。

例:

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>
)

これは、複数のコンポーネントのレンダリングを遅らせると同時に、 読み込み状態を 1 つだけ示しています。すべてのコンポーネントが完了したら 同時に表示されます。

これを確認するには、次の埋め込みを使用します。

これを行わないと、段階的な読み込みの問題が発生しやすくなります。 UI のさまざまな部分を 1 つずつ順に読み込みます。 表示されます。そのため、ユーザー エクスペリエンスをより不快に感じさせる可能性があります。

読み込みエラーに対処する

Suspense を使用すると、ネットワークの実行中に一時的な読み込み状態を表示できます。 内部で行われます。しかし、これらのネットワーク リクエストが失敗した場合、 どうしてですか?オフラインになっているか、ウェブアプリが バージョニングされた URL の遅延読み込み サーバーの再デプロイ後に使用できなくなった

React には、このような読み込みを適切に処理するための標準パターンがあります。 失敗: エラー境界を使用します。こちらのドキュメントに記載されているように、 React コンポーネントは、いずれか(または (両方)のライフサイクル メソッド static getDerivedStateFromError() または componentDidCatch()

遅延読み込みの失敗を検出して処理するには、Suspense をラップします。 エラー境界として機能する親コンポーネントがあります。Google の エラー境界の 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. 経路レベルで開始してください。ルートは、Google Chat でホストされている 分割可能なアプリケーションを作成します「 React ドキュメント Suspense を使用して他のオブジェクトと react-router
  2. サイト上の大きなコンポーネントのうち、 定義できます。これらを分割 JavaScript ペイロードを最小化できます。
  3. 画面外で、にとって重要でないものは分割することを検討してください できます。