UIをツリーとして理解する
あなたのReactアプリは、多くのコンポーネントが互いにネストされ、形を成してきています。Reactはどのようにしてアプリのコンポーネント構造を追跡しているのでしょうか?
Reactや他の多くのUIライブラリは、UIをツリーとしてモデル化します。アプリをツリーとして考えることは、コンポーネント間の関係を理解するのに役立ちます。この理解は、パフォーマンスや状態管理といった将来の概念をデバッグする際に役立つでしょう。
学習内容
- Reactがコンポーネント構造をどのように「見る」か
- レンダーツリーとは何か、そしてその有用性
- モジュール依存ツリーとは何か、そしてその有用性
ツリーとしてのUI
ツリーはアイテム間の関係モデルです。UIはしばしばツリー構造を用いて表現されます。例えば、ブラウザはHTML(DOM)やCSS(CSSOM)をモデル化するためにツリー構造を使用します。モバイルプラットフォームも、ビューの階層を表現するためにツリーを使用します。


ReactはあなたのコンポーネントからUIツリーを作成します。この例では、そのUIツリーがDOMへのレンダリングに使用されます。
ブラウザやモバイルプラットフォームと同様に、Reactもツリー構造を使用して、Reactアプリ内のコンポーネント間の関係を管理およびモデル化します。これらのツリーは、データがReactアプリをどのように流れるかを理解し、レンダリングやアプリのサイズを最適化するための有用なツールです。
レンダーツリー
コンポーネントの主な特徴の一つは、他のコンポーネントを組み合わせてコンポーネントを作成できる能力です。コンポーネントをネストする際には、親コンポーネントと子コンポーネントの概念が生まれ、各親コンポーネント自体が別のコンポーネントの子である可能性があります。
Reactアプリをレンダリングするとき、この関係をツリーでモデル化することができ、それはレンダーツリーとして知られています。
以下は、インスピレーションを与える名言をレンダリングするReactアプリです。


Reactは、レンダリングされたコンポーネントで構成されるUIツリーであるレンダーツリーを作成します。
例のアプリから、上記のレンダーツリーを構築することができます。
ツリーはノードで構成され、各ノードはコンポーネントを表します。App、FancyText、Copyrightなどは、すべてツリー内のノードです。
Reactレンダーツリーのルートノードは、アプリのルートコンポーネントです。この場合、ルートコンポーネントはAppであり、Reactが最初にレンダリングするコンポーネントです。ツリー内の各矢印は、親コンポーネントから子コンポーネントを指しています。
レンダーツリーは、Reactアプリケーションの単一のレンダーパスを表します。条件付きレンダリングでは、親コンポーネントは渡されたデータに応じて異なる子コンポーネントをレンダリングする可能性があります。
アプリを更新して、インスピレーションを与える引用文または色を条件付きでレンダリングすることができます。


条件付きレンダリングでは、異なるレンダリング間で、レンダーツリーは異なるコンポーネントをレンダリングする可能性があります。
この例では、inspiration.typeの値に応じて、<FancyText>または<Color>をレンダリングする可能性があります。レンダーツリーはレンダーパスごとに異なる可能性があります。
レンダーツリーはレンダーパス間で異なる可能性がありますが、これらのツリーは一般的に、Reactアプリにおけるトップレベルコンポーネントとリーフコンポーネントを特定するのに役立ちます。トップレベルコンポーネントはルートコンポーネントに最も近いコンポーネントであり、その下にあるすべてのコンポーネントのレンダリングパフォーマンスに影響を与え、しばしば最も複雑さを含んでいます。リーフコンポーネントはツリーの下部近くにあり、子コンポーネントを持たず、しばしば頻繁に再レンダリングされます。
これらのカテゴリのコンポーネントを特定することは、アプリのデータフローとパフォーマンスを理解するのに役立ちます。
モジュール依存ツリー
Reactアプリにおけるもう一つの関係性で、ツリーでモデル化できるものは、アプリのモジュール依存関係です。コンポーネントやロジックを別々のファイルに分割すると、コンポーネント、関数、または定数をエクスポートするJSモジュールを作成します。
モジュール依存ツリーの各ノードはモジュールであり、各ブランチはそのモジュール内のimport文を表します。
前のInspirationsアプリを例にとると、モジュール依存ツリー、または略して依存ツリーを構築することができます。


Inspirationsアプリのモジュール依存ツリー。
ツリーのルートノードはルートモジュールであり、エントリポイントファイルとも呼ばれます。多くの場合、ルートコンポーネントを含むモジュールです。
同じアプリのレンダーツリーと比較すると、類似した構造がありますが、いくつかの注目すべき違いがあります:
- ツリーを構成するノードはコンポーネントではなく、モジュールを表します。
- 非コンポーネントモジュール(例:
inspirations.js)もこのツリーで表現されます。レンダーツリーはコンポーネントのみをカプセル化します。 Copyright.jsはApp.jsの下に表示されますが、レンダーツリーでは、コンポーネントであるCopyrightはInspirationGeneratorの子コンポーネントとして表示されます。これは、InspirationGeneratorがJSXをchildrenプロップとして受け取るため、Copyrightを子コンポーネントとしてレンダリングしますが、モジュールをインポートしないからです。
依存ツリーは、Reactアプリを実行するために必要なモジュールを決定するのに役立ちます。Reactアプリを本番用にビルドする際には、通常、クライアントに配信するために必要なすべてのJavaScriptをバンドルするビルドステップがあります。これを担当するツールはバンドラーと呼ばれ、バンドラーは依存ツリーを使用して含めるべきモジュールを決定します。
アプリが成長するにつれて、バンドルサイズも大きくなることがよくあります。大きなバンドルサイズは、クライアントがダウンロードして実行するのにコストがかかります。大きなバンドルサイズは、UIが描画されるまでの時間を遅らせる可能性があります。アプリの依存ツリーを把握することは、これらの問題のデバッグに役立つかもしれません。
まとめ
- ツリーは、エンティティ間の関係を表現する一般的な方法です。UIをモデル化するためによく使用されます。
- レンダーツリーは、単一のレンダリングにおけるReactコンポーネント間のネストされた関係を表します。
- 条件付きレンダリングでは、レンダーツリーは異なるレンダリング間で変化する可能性があります。異なるプロップ値では、コンポーネントは異なる子コンポーネントをレンダリングする可能性があります。
- レンダーツリーは、トップレベルコンポーネントとリーフコンポーネントを特定するのに役立ちます。トップレベルコンポーネントは、その下にあるすべてのコンポーネントのレンダリングパフォーマンスに影響を与え、リーフコンポーネントは頻繁に再レンダリングされることがよくあります。それらを特定することは、レンダリングパフォーマンスを理解しデバッグするのに有用です。
- 依存ツリーは、Reactアプリ内のモジュール依存関係を表します。
- 依存ツリーは、ビルドツールによってアプリを配信するために必要なコードをバンドルするために使用されます。
- 依存ツリーは、ペイントまでの時間を遅くする大きなバンドルサイズのデバッグや、バンドルされるコードを最適化する機会を見つけるのに役立ちます。
