ホームページ > ウェブフロントエンド > jsチュートリアル > ReactJS アプリケーションのパフォーマンスとサイズの迅速な最適化

ReactJS アプリケーションのパフォーマンスとサイズの迅速な最適化

Linda Hamilton
リリース: 2024-12-10 20:13:10
オリジナル
632 人が閲覧しました

React は、フロントエンド集中型のアプリケーションに広く使用されており、パフォーマンスとサイズを最適化する独自の方法を備えています。両方を改善すると、React パッケージのバンドル サイズにかなりの測定可能な影響が生じます。クライアントがレンダリングするアプリケーションに焦点を当てていることを考慮すると、バンドル サイズが小さいほど読み込み時間は速くなります。

サーバー側のレンダリングにより、読み込み時間がさらに短縮されます。サーバー側レンダリングでは、ユーザーが Web ページをリクエストすると、React コンポーネントがサーバー自体で HTML コードとしてレンダリングされます。次に、この事前レンダリングされたページがブラウザーに送信されるため、ユーザーは JS 読み込み時間のオーバーヘッドなしですぐにページを表示できるようになります。

しかし、それは全く別の話です。コードに微調整を加えてパッケージ バンドルのサイズを改善することに取り組み、クライアント側でレンダリングされるサイトを改善することに主に焦点を当てましょう。深く掘り下げてみましょう。

1. コード分割と動的インポート

React コードの「バンドル」とは、すべてのインポートとコードをたどって、それを「バンドル」と呼ばれる 1 つのファイルに結合するプロセスです。 Webpack、Browserify などはすでにこれを行っています。

Webpack には「コード分割」と呼ばれる機能があり、単一のバンドルを小さなチャンクに分割し、チャンクの重複を排除し、それらを「オンデマンド」でインポートします。これは、アプリケーションのロード時間に大きな影響を与えます。

module.exports = {
  // Other webpack configuration options...
  optimization: {
    splitChunks: {
      chunks: 'all', // Options: 'initial', 'async', 'all'
      minSize: 10000, // Minimum size, in bytes, for a chunk to be generated
      maxSize: 0, // Maximum size, in bytes, for a chunk to be generated
      minChunks: 1, // Minimum number of chunks that must share a module before splitting
      maxAsyncRequests: 30, // Maximum number of parallel requests when on-demand loading
      maxInitialRequests: 30, // Maximum number of parallel requests at an entry point
      automaticNameDelimiter: '~', // Delimiter for generated names
      cacheGroups: {
        defaultVendors: {
          test: /[\/]node_modules[\/]/,
          priority: -10,
          reuseExistingChunk: true,
        },
        default: {
          minChunks: 2,
          priority: -20,
          reuseExistingChunk: true,
        },
      },
    },
  },
};
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

React Suspense によるコンポーネントの遅延読み込み (React 18): これを動的インポートと組み合わせると、コンポーネントの読み込み時間に目に見える改善が見られます。

通常、親コンポーネント内に子コンポーネントをインポートするときは、静的にインポートします。実際にレンダリングする必要があるまでこのコンポーネントがインポートされないようにするには、動的インポートと React Suspense を組み合わせて使用​​します。 React Suspense を使用すると、オンデマンドでコンポーネントをロードできます。対応するコンポーネントが動的にインポートされてレンダリングされる間、フォールバック UI が表示されます。

import { lazy } from 'react';

// The lazy loaded Component has to be exported as default
const BlogSection = lazy(() => import('./BlogSection.tsx'));

export default function HomePage() {
  return (
    <>
      <Suspense fallback={<Loading />}>
        <BlogSection />
      </Suspense>
    </>
  );
}

function Loading() {
  return <h2>Component is Loading...</h2>;
}
ログイン後にコピー
ログイン後にコピー

2. 木の揺れ

これは、バンドルを作成する前に未使用のコードをすべて削除するために JavaScript バンドラーによって使用される手法です。 ES6 コードはツリーシェイク可能です。ただし、CommonJS に基づくコード (つまり、「require」を使用するコード) はツリーシェイクできません。

Webpack Bundle Analyzer は、インタラクティブなマップを使用して Webpack のサイズを視覚化するのに役立つプラグインです。

npm install --save-dev webpack-bundle-analyzer
npm install -g source-map-explorer
ログイン後にコピー

次に、上記をプラグインとして追加するように Webpack を設定します。

plugins: [
  new BundleAnalyzerPlugin(),
  new HtmlWebpackPlugin({
    template: './public/index.html', // Path to your HTML template
    filename: 'index.html', // Output HTML file name
    inject: true, // Inject all assets into the body
  }),
];
ログイン後にコピー

スクリプトが Webpack を実行するように設定されていることを確認してください:

"build": "webpack --config webpack.config.js --mode production"
ログイン後にコピー

yarn build を実行して、バンドル サイズを効果的に視覚化するのに役立つ report.html を生成します。

次のようになります:

Quick Optimization for your ReactJS Application for Performance and Size

3. 同時レンダリング

ブロッキング レンダリングとは何かを理解することから始めましょう。レンダリングのブロックとは、React がバックグラウンドでそれほど重要ではないタスクを実行していたために、メイン スレッド (UX 更新) がブロックされた場合です。これは React 16 まではそうでした。

React 18 には同時機能が導入されており、次のことが可能になります。

  • バックグラウンド更新のスケジュール設定をより詳細に制御できるようになり、メインスレッドをブロックしないことでスムーズなエンドユーザー エクスペリエンスが実現されます。
  • 状態更新の自動バッチ処理を開始する: バッチ処理とは、状態が 1 回だけ更新されるように、複数の状態更新による複数の再レンダリングをグループ化することを指します。

startTransition() フックを使用して React の更新を非緊急として管理し、React がユーザー入力やユーザーによるコンポーネントとの対話などの緊急の更新を以前の更新よりも優先できるようにします。

module.exports = {
  // Other webpack configuration options...
  optimization: {
    splitChunks: {
      chunks: 'all', // Options: 'initial', 'async', 'all'
      minSize: 10000, // Minimum size, in bytes, for a chunk to be generated
      maxSize: 0, // Maximum size, in bytes, for a chunk to be generated
      minChunks: 1, // Minimum number of chunks that must share a module before splitting
      maxAsyncRequests: 30, // Maximum number of parallel requests when on-demand loading
      maxInitialRequests: 30, // Maximum number of parallel requests at an entry point
      automaticNameDelimiter: '~', // Delimiter for generated names
      cacheGroups: {
        defaultVendors: {
          test: /[\/]node_modules[\/]/,
          priority: -10,
          reuseExistingChunk: true,
        },
        default: {
          minChunks: 2,
          priority: -20,
          reuseExistingChunk: true,
        },
      },
    },
  },
};
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

この例では、入力値が変化すると、handleChange 関数が呼び出されます。 startTransition 関数は、リスト状態の更新を非緊急としてマークするために使用されます。これにより、React は値の状態への更新を優先し、リストが大きい場合でも入力の応答性を維持できるようになります。

useDeferredValue フックを使用して、UI のビジー状態がなくなるまで値 (通常は高価な計算) を延期します。

import { lazy } from 'react';

// The lazy loaded Component has to be exported as default
const BlogSection = lazy(() => import('./BlogSection.tsx'));

export default function HomePage() {
  return (
    <>
      <Suspense fallback={<Loading />}>
        <BlogSection />
      </Suspense>
    </>
  );
}

function Loading() {
  return <h2>Component is Loading...</h2>;
}
ログイン後にコピー
ログイン後にコピー

この例では、useDeferredValue フックを使用して、UI のビジー状態が少なくなるまで値の状態を延期します。これにより、入力の更新が処理されるまで大きなリストのレンダリングを延期することで、入力の応答性を維持することができます。

同時レンダリングの主な利点:

  • 応答性の向上: React がレンダリング作業を中断できるようにすることで、UI はユーザーの操作に対する応答性を維持します。
  • 優先順位付け: React は、緊急でない更新よりも緊急の更新を優先して、よりスムーズなユーザー エクスペリエンスを保証できます。
  • パフォーマンスの向上: 高価なアップデートを延期できるため、メインスレッドへの影響が軽減され、アプリの全体的なパフォーマンスが向上します。

4. リソースの事前ロードをサポート (React 19)

ロード中にアプリケーションが大量のリソースを取得することがわかっている場合は、そのリソースをプリロードすることをお勧めします。これらのリソースには、フォント、画像、スタイルシートなどがあります。

プリロードが有益なシナリオ:

  • 子コンポーネントはリソースを使用します。その場合、親コンポーネントのレンダリング段階でプリロードできます。
  • イベント ハンドラー内でプリロードすると、このリソースを使用するページ/コンポーネントにリダイレクトされます。実際、これはレンダリング中にプリロードするよりも優れたオプションです。
module.exports = {
  // Other webpack configuration options...
  optimization: {
    splitChunks: {
      chunks: 'all', // Options: 'initial', 'async', 'all'
      minSize: 10000, // Minimum size, in bytes, for a chunk to be generated
      maxSize: 0, // Maximum size, in bytes, for a chunk to be generated
      minChunks: 1, // Minimum number of chunks that must share a module before splitting
      maxAsyncRequests: 30, // Maximum number of parallel requests when on-demand loading
      maxInitialRequests: 30, // Maximum number of parallel requests at an entry point
      automaticNameDelimiter: '~', // Delimiter for generated names
      cacheGroups: {
        defaultVendors: {
          test: /[\/]node_modules[\/]/,
          priority: -10,
          reuseExistingChunk: true,
        },
        default: {
          minChunks: 2,
          priority: -20,
          reuseExistingChunk: true,
        },
      },
    },
  },
};
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

興味深い事実: プリロードを実装した後、Shopify、Financial Times、Treebo を含む多くのサイトで、インタラクティブまでの時間やユーザーが認識する遅延などのユーザー中心の指標が 1 秒改善されました。


Quick Optimization for your ReactJS Application for Performance and Size

フィードバックを残してください

このブログがお役に立てば幸いです!あなたのフィードバックは私にとって非常に貴重です ご意見やご提案を下のコメント欄に残してください。

さらに詳しい情報や最新情報が必要な場合は、LinkedIn でお気軽にご連絡ください。つながりを保ち、一緒に学び、成長し続けましょう!

以上がReactJS アプリケーションのパフォーマンスとサイズの迅速な最適化の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:dev.to
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
著者別の最新記事
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート