Reactのパフォーマンスを最適化するためのツールの比較

アプリのパフォーマンスを最適化しない場合、Reactアプリケーションを構築するときに発生する可能性のある一般的な問題は、Webページのフリーズ、UXの低下、多数のコンポーネントの処理、レンダリングの遅延、および不要な再レンダリングです。

この記事では、Reactアプリケーションの潜在的な問題を特定して、UXの完成度を高めるのに役立つパフォーマンス最適化ツールについて説明します。これらのツールには、Profiler API React.memo()、、およびReactDeveloperToolsが含まれます。

プロファイラーAPI

Profiler API(Chrome Devツールのものではありません)は、B。Vaughnによって開発された比較的新しいReactコンポーネントです。これは、コンポーネントが再レンダリングされる回数とレンダリングの「コスト」、つまり、その再レンダリングによって影響を受ける時間とリソースを追跡する手段を提供します。

これを使用すると、メモ化によって最適化する必要がある可能性のある、アプリケーションの低速で欠陥のある領域をすばやく特定できます。

ProfilerAPIの使用方法

Profiler APIには通常、2つの小道具が必要です。とは、によってラップされたコンポーネントがマウントまたは更新されるたびに時間メトリックを収集idするコールバック関数です。これは、Reactアプリで遅れているコンポーネントを検出するための非常に効率的なツールです。onRender<Profiler />

以下のコードスニペットは、Footerコンポーネントのプロファイルを作成する方法を示しています。

import React, { Profiler } from "react";
return(
  <App>
    <Profiler id="Footer" onRender={callback}>
      <Footer {...props} />
    </Profiler>
    <Main {...props} />
  </App>
);

複数の<Profiler/>コンポーネントを使用して、アプリケーションのさまざまな部分を追跡することもできます。

return(
  <App>
    <Profiler id="Footer" onRender={callback}>
      <Footer {...props} />
    </Profiler>
    <Profiler id="Main" onRender={callback}>
      <Main {...props} />
    </Profiler>
  </App>
);

<Profiler />コンポーネントは、同じツリー内の個別のコンポーネントにアクセスできる方法でネストすることもできます。

return(
  <App>
    <Profiler id="Panel" onRender={callback}>
      <Panel {...props}>
        <Profiler id="Main" onRender={callback}>
          <Main {...props} />
        </Profiler>
        <Profiler id="PreviewPane" onRender={callback}>
          <PreviewPane {...props} />
        </Profiler>
      </Panel>
    </Profiler>
  </App>
);

これらは、を使用し<Profiler />てアプリケーションのパフォーマンスを追跡するためのさまざまな方法です。

コールonRenderバック

は小道具として<Profiler/>のメソッドが必要です。onRenderこの関数は、プロファイルツリーのコンポーネントが変更を「コミット」したときに実行されます。レンダリングされた内容と所要時間に関する情報を取得します。

function callback(id, phase, actualTime, baseTime, startTime, commitTime, interactions) {
  // aggregate or log render timings...
} 

それでは、小道具を定義しましょう。

  • id小道具は、プロファイラーレポートを識別するために使用されます。複数のプロファイラーを使用している場合、これはツリーのどの部分が侵害されたかを把握するのに役立ちます
  • phase(mount/update)コンポーネントツリーが初めてマウントされたか、小道具、状態、またはフックの変更に基づいて再レンダリングされたかを報告します
  • actualTimeプロファイラーがその子孫をマウントまたは更新するのにかかった時間です
  • baseTime各コンポーネントの最新のレンダリング時間の長さです
  • startTimeプロファイラーが子孫のマウント/レンダリング時間を測定し始めたときのタイムスタンプです
  • commitTime更新をコミットするのにかかった時間です。すべてのプロファイラーはコミットでこの値を共有し、必要に応じてそれらをグループ化できるようにします
  • interactionsは、更新がスケジュールされたときに追跡される「相互作用」のセットです。たとえば、setState機能をスケジュールするときなどです。

インタラクションを追跡するためのAPIはまだ実験段階ですが、更新の原因を特定するときに非常に効果的になる可能性があります。あなたはここでそれについてもっと学ぶことができます。

import React, { Profiler } from "react";
const callback = (id, phase, actualTime, baseTime, startTime, commitTime) => {
  console.log(`${id}'s ${phase} phase:`);
  console.log(`Actual time: ${actualTime}`);
  console.log(`Base time: ${baseTime}`);
  console.log(`Start time: ${startTime}`);
  console.log(`Commit time: ${commitTime}`);
};
return (
    <>
      <Profiler id="CurrencyInput" onRender={callback}>
      <CurrencyInput
         props={props}
         />
        </Profiler>
    </>
);

上記の例で<Profiler/>は、コンポーネントがラップされており、CurrencyInputマウント時にこのコンポーネントに関する多くの役立つ情報にアクセスできます。この場合、コンソールでその情報にアクセスできます。

これらのパラメーターは、どのコンポーネントツリーがアプリの速度を低下させ、どのコンポーネントツリーが良好に機能しているかを判断するのに役立ちます。

ProfilerAPIのユースケース

<Profiler />次の場合に使用できます。

  • プログラムで特定のアプリコンポーネントのタイミングを取得する予定です
  • どの特定のユーザーアクションまたはバックエンドリクエストがレンダリングを非常に遅くする原因となったかを特定する必要があります
  • よりセマンティックなコンテキストでパフォーマンスの結果を提供したい

プロファイラーAPIの欠点

  • ReactDevToolsProfilerほど多くのレンダリング情報が得られるとは限りません。
  • コストがかかります。コンポーネントツリーの各プロファイラーインスタンスには、わずかなパフォーマンスの低下が発生します

Profiler APIは、パフォーマンスへの影響が小さいため、ごく最近、本番ビルドで無効にされました。ほとんどの深刻なパフォーマンスの問題は本番ビルドと開発ビルドで顕著になるため、これは通常は問題になりませんが、常にそうであるとは限りません。場合によっては、本番バンドルでコンポーネントのレンダリング時間にアクセスしたいことがあります。

React.memo()

React.memo()不要な再レンダリングを処理するときに便利になりがちな機能です。マウント/更新時にプロップが変更されていない場合、Reactがコンポーネントの再レンダリングをスキップするようにすることで、機能コンポーネントとフックのレンダリング効率を向上させるのに役立ちます。メモ化のmemo略です。

使い方React.memo()

関数コンポーネントを関数でラップするReact.memo()ことは、それを使用する最も一般的な方法です。

const Stone = React.memo(() => {
  return (
    <div className="black-stone">
      <Task />
    </div>
  );
});

以下の例を考えてみましょう。

const Component1 = () => {
  console.log("Component 1 rendered")
  return (
    <>
      <p>Component 1</p>
      </>
  )
}
const Component2 = () => {
  console.log("Component 2 rendered")
  return (
    <div>
      <p>Component 2</p>
      </div>
  )
}
const SampleApp = () => {
  const [counter, setCounter] = React.useState(0)
  return (
    <div>
      <div>Count: {counter}</div>
      <Component1 />
      <Component2 />
      <button onClick={() => setCounter(counter + 1)}>increase count</button>
  </div>
  )
}

上記のコードは、コンポーネントによって格納されているComponent1との2つのコンポーネントを含む単純なReactアプリケーションです。これらの2つのコンポーネントは、レンダリングまたは再レンダリングされるたびにコンソールに報告されます。Component2App

コンポーネントには、カウントの増加Appボタンをクリックすると動的に変化するカウンター状態変数もあり、再レンダリングを引き起こします。Component1Component2

ボタンを4回クリックすると(カウントが4に増えます)、コンポーネントごとに5つのログがあることがわかります。1つは初期レンダリング用で、ボタンがクリックされるたびに(つまり、これらのコンポーネントがクリックされるたびに)追加の4つです。再レンダリング)。これはパフォーマンスの問題であり、小さなプロジェクトでは見過ごされる可能性があるため無視する傾向がありますが、はるかに大きなプロジェクトでは再生されるため、アプリが冗長で低速になります。

良いニュースは、でこの問題をすばやく修正できることですReact.memo()。たとえばComponent1、ボタンをクリックしたときに再レンダリングしたくない場合は、次のようにします。

const Component1 = React.memo(function Component1(props) {
  console.log("Component 1 rendered")
  return (
    <div>
      <p>Component 1</p>
      </div>
  )
});

でラップComponent1React.memo()たので、コンソールに戻って、それがアプリにどのように影響するかを見てみましょう。

ご覧のとおりComponent1、カウンターを増やしても再レンダリングしないため、問題は解決します。

のユースケースReact.memo()

React.memo()次の場合に使用するのが最適です。

  • コンポーネントのレンダリング時間は100ms以上です
  • コンポーネントは同じ小道具のセットに対して再レンダリングを続けます。これは、親コンポーネントが子コンポーネントにレンダリングを強制するときによく発生します。
  • 多数のUIコンポーネントを備えた大規模なアプリケーションを扱っている場合、再レンダリングすると、ユーザーの応答遅延が顕著になります(UXが不十分)

の欠点React.memo()

React.memo()パフォーマンス上の利点を評価できない場合は、使用を避けてください。コンポーネント(この高次コンポーネントがある場合とない場合)を再レンダリングするための計算時間が短いか存在しない場合、利用することReact.memo()は無意味です。

ラップクラスコンポーネントをに含めることは可能ですがReact.memo、これは悪い習慣と見なされるため、お勧めできません。代わりに、PureComponentクラスを拡張する方が望ましいです。これは、クラスコンポーネントをメモ化するためのはるかにクリーンな方法です。

経験則として、パフォーマンスの利点を測定できない場合は、メモ化を使用しないでください。

React開発者ツール

Reactには、ReactDeveloperToolsと呼ばれるChromeDevTools拡張機能があります⚛️React Developerツールには、コンポーネント⚛️プロファイラーの2つのタブがあります。

[コンポーネント]タブでは、アプリのコンポーネント階層とその状態情報にアクセスできます。ルートReactコンポーネントとページにレンダリングされたサブコンポーネントの両方が表示されます。

[プロファイラー]タブは、アプリの構造とコンポーネントのレンダリング時間の完全なアナロジーを提供するため、パフォーマンスの最適化に役立ちます。

React Developer Toolsにアクセスするには、Reactv.16.5以降を使用している必要があることに注意してください。

プロファイラーの使用

Reactアプリケーションをプロファイリングすることで、アプリの総合的なパフォーマンスを示す必要なすべてのデータを簡単に取得できます。これにより、でメモ化することでアプリを最適化できますReact.memo()

プロファイラーを使用するには、次の3つの簡単な手順があります。

  1. [プロファイラー]タブの[記録]ボタンをクリックします。これにより、アプリケーションのアクティビティとその一般的なUIの動作にアクセスできます。
  2. 通常どおりにアプリの通常の操作を実行します(この時点で、プロファイラーはアプリケーションの再レンダリングに関するデータを収集します)
  3. 録音ボタンをもう一度クリックして、録音を停止します

結果の解釈

通常、Reactは2つのフェーズで実行されます。1つは、どのDOM変更を行うかを決定するレンダリングフェーズ、もう1つは、アクションが実際に実行されるコミットフェーズです。

Reactのプロファイラーはアプリのパフォーマンス情報を照合し、以下に示すように棒グラフで表されるコミットの形式でそれらを表示します。

これらのチャートには、3つの異なる形式があります。

炎のグラフ

このグラフは、単一のコミットに対するコンポーネントの現在の状態を表しています。各バーはアプリ内のコンポーネントを表し、各バーの長さは対応するコンポーネントのレンダリング時間によって決定されるため、コンポーネントのレンダリング時間が長くなるほど、バーは長くなります。

上記のアプリは、Router.ProviderのレンダリングにRouter.Consumerよりも時間がかかったことを示しています。各バーをクリックすると、各コンポーネントの特定のコミット情報を取得できます。

また、バーの色を見ることで、各コンポーネントのレンダリングにかかった時間を知ることができます。色は次のように解釈されます。

  • 灰色:コミット中にコンポーネントをレンダリングできませんでした
  • 青緑:コンポーネントのレンダリングに比較的時間がかかりませんでした
  • 黄緑色:コンポーネントのレンダリングに比較的時間がかかりました
  • 黄色:コンポーネントのレンダリングに最も時間がかかりました

ランクグラフ

このグラフは、レンダリングまたは再レンダリングする各コンポーネントの時間のランク付けされた順序で結果を表示します。最も時間がかかるコンポーネントが一番上にあります。

このグラフを使用すると、どのコンポーネントがアプリケーションの速度を低下させ、どのコンポーネントがページのリロードに最も影響を与えるかをすぐに検出できます。

上記のサンプルアプリから、ルーターのレンダリング時間が最も長くなっています。

コンポーネントチャート

コンポーネントを表すバーをダブルクリックすると、コンポーネントのチャートにアクセスできます。このチャートは、プロファイリング時間中のコンポーネントのライフサイクルに関する情報を提供します。

前述したように、プロファイラーは、アプリの実行時間、コンポーネントの再レンダリング時間、コミット情報などの役立つ情報を提供します。これらの結果は、さまざまな方法でアプリケーションの概要を示し、どのコンポーネントが長いレンダリングを引き起こしているのかを把握し、メモ化などの手法を使用してそれらを最適化して、不要な再レンダリングを回避できるため、不可欠です。

このChromeDevToolsプラグインを正常に使用する方法を学習した後、Reactアプリケーションのパフォーマンスの問題を明らかにするのは簡単です。

React開発者ツールのユースケース

React Developer Toolsは、次の場合に使用できます。

  • コンポーネントごとに、アプリのパフォーマンスをグラフィカルに視覚化する必要があります
  • 各コンポーネントのレンダリング時間と、特に非常に大きなコンポーネントの場合、アプリケーションの遅延またはフリーズを引き起こす可能性のあるコンポーネントを追跡する必要があります。
  • コンソール内のコンポーネントと状態の情報にアクセスしたい

React開発者ツールの欠点

プロファイラーはアプリのコンポーネント情報へのアクセスを提供しますが、問題を積極的に解決するのではなく、問題を表示するだけです。アプリのパフォーマンスを向上させるには、メモ化などの最適化手法を積極的に適用する必要があります。

React用語でのメモ化は、親コンポーネントが再レンダリングされたときに小道具が変更された場合にのみ子コンポーネントが再レンダリングされる最適化手法です。小道具が変更されないままの場合、renderメソッドをスキップして、キャッシュされた結果を返します。

比較表

 React Developer Tools ProfilerプロファイラーAPI(<Profiler />)React.memo()
それは何をするためのものか?アプリケーションを分析し、結果のグラフィック表現を返します。アプリケーションを分析し、結果のプログラム表現を生成します。得られた結果に基づいて、必要に応じてコンポーネントをメモ化するために使用されます。
コンポーネントのレンダリング時間を表示しますか?はいはいいいえ
プロダクションバンドルで効果的ですか?いいえいいえはい

これらのツールを見ると、React Dev Tools Profilerは、使いやすく、十分に文書化されており、グラフのようにコンポーネントツリー構造に完全にアクセスできるという理由だけで私にとっては最前線に立っています。Reactアプリケーションでパフォーマンスの「一時的な中断」を特定するのは簡単ではありません。

結論

このガイドでは、Reactアプリのプロファイリングとパフォーマンスの問題の特定に使用できるツールのいくつかを示しました。また、メモ化と、このReact.memo()関数を使用してアプリの全体的なパフォーマンスを向上させる方法についても説明しました。ハッピーコーディング!

 このストーリーは、もともとhttps://blog.logrocket.com/comparing-tools-optimizing-performance-react/で公開されました

#react-native 

What is GEEK

Buddha Community

Reactのパフォーマンスを最適化するためのツールの比較

Reactのパフォーマンスを最適化するためのツールの比較

アプリのパフォーマンスを最適化しない場合、Reactアプリケーションを構築するときに発生する可能性のある一般的な問題は、Webページのフリーズ、UXの低下、多数のコンポーネントの処理、レンダリングの遅延、および不要な再レンダリングです。

この記事では、Reactアプリケーションの潜在的な問題を特定して、UXの完成度を高めるのに役立つパフォーマンス最適化ツールについて説明します。これらのツールには、Profiler API React.memo()、、およびReactDeveloperToolsが含まれます。

プロファイラーAPI

Profiler API(Chrome Devツールのものではありません)は、B。Vaughnによって開発された比較的新しいReactコンポーネントです。これは、コンポーネントが再レンダリングされる回数とレンダリングの「コスト」、つまり、その再レンダリングによって影響を受ける時間とリソースを追跡する手段を提供します。

これを使用すると、メモ化によって最適化する必要がある可能性のある、アプリケーションの低速で欠陥のある領域をすばやく特定できます。

ProfilerAPIの使用方法

Profiler APIには通常、2つの小道具が必要です。とは、によってラップされたコンポーネントがマウントまたは更新されるたびに時間メトリックを収集idするコールバック関数です。これは、Reactアプリで遅れているコンポーネントを検出するための非常に効率的なツールです。onRender<Profiler />

以下のコードスニペットは、Footerコンポーネントのプロファイルを作成する方法を示しています。

import React, { Profiler } from "react";
return(
  <App>
    <Profiler id="Footer" onRender={callback}>
      <Footer {...props} />
    </Profiler>
    <Main {...props} />
  </App>
);

複数の<Profiler/>コンポーネントを使用して、アプリケーションのさまざまな部分を追跡することもできます。

return(
  <App>
    <Profiler id="Footer" onRender={callback}>
      <Footer {...props} />
    </Profiler>
    <Profiler id="Main" onRender={callback}>
      <Main {...props} />
    </Profiler>
  </App>
);

<Profiler />コンポーネントは、同じツリー内の個別のコンポーネントにアクセスできる方法でネストすることもできます。

return(
  <App>
    <Profiler id="Panel" onRender={callback}>
      <Panel {...props}>
        <Profiler id="Main" onRender={callback}>
          <Main {...props} />
        </Profiler>
        <Profiler id="PreviewPane" onRender={callback}>
          <PreviewPane {...props} />
        </Profiler>
      </Panel>
    </Profiler>
  </App>
);

これらは、を使用し<Profiler />てアプリケーションのパフォーマンスを追跡するためのさまざまな方法です。

コールonRenderバック

は小道具として<Profiler/>のメソッドが必要です。onRenderこの関数は、プロファイルツリーのコンポーネントが変更を「コミット」したときに実行されます。レンダリングされた内容と所要時間に関する情報を取得します。

function callback(id, phase, actualTime, baseTime, startTime, commitTime, interactions) {
  // aggregate or log render timings...
} 

それでは、小道具を定義しましょう。

  • id小道具は、プロファイラーレポートを識別するために使用されます。複数のプロファイラーを使用している場合、これはツリーのどの部分が侵害されたかを把握するのに役立ちます
  • phase(mount/update)コンポーネントツリーが初めてマウントされたか、小道具、状態、またはフックの変更に基づいて再レンダリングされたかを報告します
  • actualTimeプロファイラーがその子孫をマウントまたは更新するのにかかった時間です
  • baseTime各コンポーネントの最新のレンダリング時間の長さです
  • startTimeプロファイラーが子孫のマウント/レンダリング時間を測定し始めたときのタイムスタンプです
  • commitTime更新をコミットするのにかかった時間です。すべてのプロファイラーはコミットでこの値を共有し、必要に応じてそれらをグループ化できるようにします
  • interactionsは、更新がスケジュールされたときに追跡される「相互作用」のセットです。たとえば、setState機能をスケジュールするときなどです。

インタラクションを追跡するためのAPIはまだ実験段階ですが、更新の原因を特定するときに非常に効果的になる可能性があります。あなたはここでそれについてもっと学ぶことができます。

import React, { Profiler } from "react";
const callback = (id, phase, actualTime, baseTime, startTime, commitTime) => {
  console.log(`${id}'s ${phase} phase:`);
  console.log(`Actual time: ${actualTime}`);
  console.log(`Base time: ${baseTime}`);
  console.log(`Start time: ${startTime}`);
  console.log(`Commit time: ${commitTime}`);
};
return (
    <>
      <Profiler id="CurrencyInput" onRender={callback}>
      <CurrencyInput
         props={props}
         />
        </Profiler>
    </>
);

上記の例で<Profiler/>は、コンポーネントがラップされており、CurrencyInputマウント時にこのコンポーネントに関する多くの役立つ情報にアクセスできます。この場合、コンソールでその情報にアクセスできます。

これらのパラメーターは、どのコンポーネントツリーがアプリの速度を低下させ、どのコンポーネントツリーが良好に機能しているかを判断するのに役立ちます。

ProfilerAPIのユースケース

<Profiler />次の場合に使用できます。

  • プログラムで特定のアプリコンポーネントのタイミングを取得する予定です
  • どの特定のユーザーアクションまたはバックエンドリクエストがレンダリングを非常に遅くする原因となったかを特定する必要があります
  • よりセマンティックなコンテキストでパフォーマンスの結果を提供したい

プロファイラーAPIの欠点

  • ReactDevToolsProfilerほど多くのレンダリング情報が得られるとは限りません。
  • コストがかかります。コンポーネントツリーの各プロファイラーインスタンスには、わずかなパフォーマンスの低下が発生します

Profiler APIは、パフォーマンスへの影響が小さいため、ごく最近、本番ビルドで無効にされました。ほとんどの深刻なパフォーマンスの問題は本番ビルドと開発ビルドで顕著になるため、これは通常は問題になりませんが、常にそうであるとは限りません。場合によっては、本番バンドルでコンポーネントのレンダリング時間にアクセスしたいことがあります。

React.memo()

React.memo()不要な再レンダリングを処理するときに便利になりがちな機能です。マウント/更新時にプロップが変更されていない場合、Reactがコンポーネントの再レンダリングをスキップするようにすることで、機能コンポーネントとフックのレンダリング効率を向上させるのに役立ちます。メモ化のmemo略です。

使い方React.memo()

関数コンポーネントを関数でラップするReact.memo()ことは、それを使用する最も一般的な方法です。

const Stone = React.memo(() => {
  return (
    <div className="black-stone">
      <Task />
    </div>
  );
});

以下の例を考えてみましょう。

const Component1 = () => {
  console.log("Component 1 rendered")
  return (
    <>
      <p>Component 1</p>
      </>
  )
}
const Component2 = () => {
  console.log("Component 2 rendered")
  return (
    <div>
      <p>Component 2</p>
      </div>
  )
}
const SampleApp = () => {
  const [counter, setCounter] = React.useState(0)
  return (
    <div>
      <div>Count: {counter}</div>
      <Component1 />
      <Component2 />
      <button onClick={() => setCounter(counter + 1)}>increase count</button>
  </div>
  )
}

上記のコードは、コンポーネントによって格納されているComponent1との2つのコンポーネントを含む単純なReactアプリケーションです。これらの2つのコンポーネントは、レンダリングまたは再レンダリングされるたびにコンソールに報告されます。Component2App

コンポーネントには、カウントの増加Appボタンをクリックすると動的に変化するカウンター状態変数もあり、再レンダリングを引き起こします。Component1Component2

ボタンを4回クリックすると(カウントが4に増えます)、コンポーネントごとに5つのログがあることがわかります。1つは初期レンダリング用で、ボタンがクリックされるたびに(つまり、これらのコンポーネントがクリックされるたびに)追加の4つです。再レンダリング)。これはパフォーマンスの問題であり、小さなプロジェクトでは見過ごされる可能性があるため無視する傾向がありますが、はるかに大きなプロジェクトでは再生されるため、アプリが冗長で低速になります。

良いニュースは、でこの問題をすばやく修正できることですReact.memo()。たとえばComponent1、ボタンをクリックしたときに再レンダリングしたくない場合は、次のようにします。

const Component1 = React.memo(function Component1(props) {
  console.log("Component 1 rendered")
  return (
    <div>
      <p>Component 1</p>
      </div>
  )
});

でラップComponent1React.memo()たので、コンソールに戻って、それがアプリにどのように影響するかを見てみましょう。

ご覧のとおりComponent1、カウンターを増やしても再レンダリングしないため、問題は解決します。

のユースケースReact.memo()

React.memo()次の場合に使用するのが最適です。

  • コンポーネントのレンダリング時間は100ms以上です
  • コンポーネントは同じ小道具のセットに対して再レンダリングを続けます。これは、親コンポーネントが子コンポーネントにレンダリングを強制するときによく発生します。
  • 多数のUIコンポーネントを備えた大規模なアプリケーションを扱っている場合、再レンダリングすると、ユーザーの応答遅延が顕著になります(UXが不十分)

の欠点React.memo()

React.memo()パフォーマンス上の利点を評価できない場合は、使用を避けてください。コンポーネント(この高次コンポーネントがある場合とない場合)を再レンダリングするための計算時間が短いか存在しない場合、利用することReact.memo()は無意味です。

ラップクラスコンポーネントをに含めることは可能ですがReact.memo、これは悪い習慣と見なされるため、お勧めできません。代わりに、PureComponentクラスを拡張する方が望ましいです。これは、クラスコンポーネントをメモ化するためのはるかにクリーンな方法です。

経験則として、パフォーマンスの利点を測定できない場合は、メモ化を使用しないでください。

React開発者ツール

Reactには、ReactDeveloperToolsと呼ばれるChromeDevTools拡張機能があります⚛️React Developerツールには、コンポーネント⚛️プロファイラーの2つのタブがあります。

[コンポーネント]タブでは、アプリのコンポーネント階層とその状態情報にアクセスできます。ルートReactコンポーネントとページにレンダリングされたサブコンポーネントの両方が表示されます。

[プロファイラー]タブは、アプリの構造とコンポーネントのレンダリング時間の完全なアナロジーを提供するため、パフォーマンスの最適化に役立ちます。

React Developer Toolsにアクセスするには、Reactv.16.5以降を使用している必要があることに注意してください。

プロファイラーの使用

Reactアプリケーションをプロファイリングすることで、アプリの総合的なパフォーマンスを示す必要なすべてのデータを簡単に取得できます。これにより、でメモ化することでアプリを最適化できますReact.memo()

プロファイラーを使用するには、次の3つの簡単な手順があります。

  1. [プロファイラー]タブの[記録]ボタンをクリックします。これにより、アプリケーションのアクティビティとその一般的なUIの動作にアクセスできます。
  2. 通常どおりにアプリの通常の操作を実行します(この時点で、プロファイラーはアプリケーションの再レンダリングに関するデータを収集します)
  3. 録音ボタンをもう一度クリックして、録音を停止します

結果の解釈

通常、Reactは2つのフェーズで実行されます。1つは、どのDOM変更を行うかを決定するレンダリングフェーズ、もう1つは、アクションが実際に実行されるコミットフェーズです。

Reactのプロファイラーはアプリのパフォーマンス情報を照合し、以下に示すように棒グラフで表されるコミットの形式でそれらを表示します。

これらのチャートには、3つの異なる形式があります。

炎のグラフ

このグラフは、単一のコミットに対するコンポーネントの現在の状態を表しています。各バーはアプリ内のコンポーネントを表し、各バーの長さは対応するコンポーネントのレンダリング時間によって決定されるため、コンポーネントのレンダリング時間が長くなるほど、バーは長くなります。

上記のアプリは、Router.ProviderのレンダリングにRouter.Consumerよりも時間がかかったことを示しています。各バーをクリックすると、各コンポーネントの特定のコミット情報を取得できます。

また、バーの色を見ることで、各コンポーネントのレンダリングにかかった時間を知ることができます。色は次のように解釈されます。

  • 灰色:コミット中にコンポーネントをレンダリングできませんでした
  • 青緑:コンポーネントのレンダリングに比較的時間がかかりませんでした
  • 黄緑色:コンポーネントのレンダリングに比較的時間がかかりました
  • 黄色:コンポーネントのレンダリングに最も時間がかかりました

ランクグラフ

このグラフは、レンダリングまたは再レンダリングする各コンポーネントの時間のランク付けされた順序で結果を表示します。最も時間がかかるコンポーネントが一番上にあります。

このグラフを使用すると、どのコンポーネントがアプリケーションの速度を低下させ、どのコンポーネントがページのリロードに最も影響を与えるかをすぐに検出できます。

上記のサンプルアプリから、ルーターのレンダリング時間が最も長くなっています。

コンポーネントチャート

コンポーネントを表すバーをダブルクリックすると、コンポーネントのチャートにアクセスできます。このチャートは、プロファイリング時間中のコンポーネントのライフサイクルに関する情報を提供します。

前述したように、プロファイラーは、アプリの実行時間、コンポーネントの再レンダリング時間、コミット情報などの役立つ情報を提供します。これらの結果は、さまざまな方法でアプリケーションの概要を示し、どのコンポーネントが長いレンダリングを引き起こしているのかを把握し、メモ化などの手法を使用してそれらを最適化して、不要な再レンダリングを回避できるため、不可欠です。

このChromeDevToolsプラグインを正常に使用する方法を学習した後、Reactアプリケーションのパフォーマンスの問題を明らかにするのは簡単です。

React開発者ツールのユースケース

React Developer Toolsは、次の場合に使用できます。

  • コンポーネントごとに、アプリのパフォーマンスをグラフィカルに視覚化する必要があります
  • 各コンポーネントのレンダリング時間と、特に非常に大きなコンポーネントの場合、アプリケーションの遅延またはフリーズを引き起こす可能性のあるコンポーネントを追跡する必要があります。
  • コンソール内のコンポーネントと状態の情報にアクセスしたい

React開発者ツールの欠点

プロファイラーはアプリのコンポーネント情報へのアクセスを提供しますが、問題を積極的に解決するのではなく、問題を表示するだけです。アプリのパフォーマンスを向上させるには、メモ化などの最適化手法を積極的に適用する必要があります。

React用語でのメモ化は、親コンポーネントが再レンダリングされたときに小道具が変更された場合にのみ子コンポーネントが再レンダリングされる最適化手法です。小道具が変更されないままの場合、renderメソッドをスキップして、キャッシュされた結果を返します。

比較表

 React Developer Tools ProfilerプロファイラーAPI(<Profiler />)React.memo()
それは何をするためのものか?アプリケーションを分析し、結果のグラフィック表現を返します。アプリケーションを分析し、結果のプログラム表現を生成します。得られた結果に基づいて、必要に応じてコンポーネントをメモ化するために使用されます。
コンポーネントのレンダリング時間を表示しますか?はいはいいいえ
プロダクションバンドルで効果的ですか?いいえいいえはい

これらのツールを見ると、React Dev Tools Profilerは、使いやすく、十分に文書化されており、グラフのようにコンポーネントツリー構造に完全にアクセスできるという理由だけで私にとっては最前線に立っています。Reactアプリケーションでパフォーマンスの「一時的な中断」を特定するのは簡単ではありません。

結論

このガイドでは、Reactアプリのプロファイリングとパフォーマンスの問題の特定に使用できるツールのいくつかを示しました。また、メモ化と、このReact.memo()関数を使用してアプリの全体的なパフォーマンスを向上させる方法についても説明しました。ハッピーコーディング!

 このストーリーは、もともとhttps://blog.logrocket.com/comparing-tools-optimizing-performance-react/で公開されました

#react-native