React 18は何年もかけて開発され、Reactチームにとって貴重な教訓をもたらしました。そのリリースは、長年の研究と多くの道筋の探求の結果でした。成功した道筋もあれば、新たな洞察につながった行き止まりも数多くありました。私たちが学んだ教訓の一つは、コミュニティが私たちの探求している道筋への洞察を持たずに新機能を待つのは、フラストレーションが溜まるということです。
私たちは通常、より実験的なものから明確に定義されたものまで、同時に多くのプロジェクトに取り組んでいます。今後は、これらのプロジェクト全体で私たちが取り組んでいることについて、コミュニティと定期的により多くを共有していきたいと考えています。
期待値を設定するために申し上げると、これは明確なタイムラインを持つロードマップではありません。これらのプロジェクトの多くは活発な研究段階にあり、具体的な出荷日を設定するのは困難です。学習内容によっては、現在の反復では決して出荷されない可能性もあります。代わりに、私たちが積極的に考えている問題領域と、これまでに学んだことを共有したいと思います。
Server Components
私たちは2020年12月にReact Server Components(RSC)の実験的デモを発表しました。それ以来、React 18でその依存関係を完成させ、実験的フィードバックに触発された変更に取り組んできました。
特に、フォークされたI/Oライブラリ(例:react-fetch)を持つというアイデアを放棄し、より良い互換性のためにasync/awaitモデルを採用しています。ルーターをデータフェッチに使用することもできるため、これは技術的にはRSCのリリースを阻害しません。
もう一つの変更は、ファイル拡張子アプローチから境界の注釈付けに移行していることです。
私たちはVercelとShopifyと協力して、webpackとViteの両方で共有セマンティクスのバンドラーサポートを統一しています。ローンチ前に、RSCのセマンティクスがReactエコシステム全体で同じであることを確認したいと考えています。これが安定版に到達するための主要な障害です。
Asset Loading
現在、スクリプト、外部スタイル、フォント、画像などのアセットは、通常外部システムを使用してプリロードおよびロードされます。これにより、ストリーミング、Server Components、その他の新しい環境間での調整が困難になる可能性があります。
私たちは、すべてのReact環境で動作するReact APIを通じて、重複排除された外部アセットをプリロードおよびロードするAPIの追加を検討しています。また、これらがSuspenseをサポートし、画像、CSS、フォントがロードされるまで表示をブロックするが、ストリーミングと並行レンダリングはブロックしないようにすることも検討しています。これにより、ビジュアルがポップしてレイアウトシフトが発生する「ポップコーン現象」を回避できます。
Static Server Rendering Optimizations
Static Site Generation(SSG)とIncremental Static Regeneration(ISR)は、キャッシュ可能なページのパフォーマンスを得る優れた方法ですが、動的なServer Side Rendering(SSR)のパフォーマンスを向上させる機能を追加できると考えています。特に、コンテンツの大部分がキャッシュ可能だが、すべてではない場合です。
私たちは、コンパイルと静的パスを活用してサーバーレンダリングを最適化する方法を探求しています。
React Optimizing Compiler
私たちはReact Conf 2021でReact Forgetの早期プレビューを提供しました。これは、Reactのプログラミングモデルを保持しながら、再レンダリングのコストを最小化するために、useMemoとuseCallbackの呼び出しと同等のものを自動的に生成するコンパイラです。
最近、コンパイラをより信頼性が高く、より有能にするために書き直しを完了しました。この新しいアーキテクチャにより、ローカルミューテーションの使用などのより複雑なパターンを分析およびメモ化でき、メモ化Hooksと同等であることを超えた多くの新しいコンパイル時最適化の機会が開かれます。
私たちはまた、コンパイラの多くの側面を探求するためのプレイグラウンドにも取り組んでいます。プレイグラウンドの目標はコンパイラの開発を容易にすることですが、それを試して、コンパイラが何をするかについての直感を構築することも容易になると考えています。それは内部でどのように動作するかについてのさまざまな洞察を明らかにし、入力時にコンパイラの出力をライブレンダリングします。これは、リリース時にコンパイラと一緒に出荷されます。
Offscreen
今日、コンポーネントを非表示にしたり表示したりしたい場合、2つのオプションがあります。1つは、ツリーから完全に追加または削除することです。このアプローチの問題は、アンマウントするたびに、スクロール位置などのDOMに保存された状態を含む、UIの状態が失われることです。
もう1つのオプションは、コンポーネントをマウントしたままにして、CSSを使用して外観を視覚的に切り替えることです。これによりUIの状態は保持されますが、Reactは新しい更新を受信するたびに非表示のコンポーネントとそのすべての子をレンダリングし続ける必要があるため、パフォーマンスコストが発生します。
Offscreenは3番目のオプションを導入します:UIを視覚的に非表示にしますが、そのコンテンツの優先度を下げます。このアイデアは、content-visibility CSSプロパティと精神的に似ています:コンテンツが非表示の場合、UIの残りの部分と同期を保つ必要がありません。Reactは、アプリの残りの部分がアイドル状態になるまで、またはコンテンツが再び表示されるまで、レンダリング作業を延期できます。
Offscreenは、高レベル機能のロックを解除する低レベル機能です。startTransitionなどのReactの他の並行機能と同様に、ほとんどの場合、Offscreen APIと直接やり取りするのではなく、次のようなパターンを実装するために意見のあるフレームワークを介してやり取りします:
- インスタント遷移:一部のルーティングフレームワークは、リンクにホバーしたときなど、後続のナビゲーションを高速化するためにデータをプリフェッチしています。Offscreenを使用すると、バックグラウンドで次の画面をプリレンダリングすることもできます。
- 再利用可能な状態:同様に、ルートやタブ間をナビゲートするときに、Offscreenを使用して前の画面の状態を保持し、戻って中断したところから再開できます。
- 仮想化リストレンダリング:大きなアイテムリストを表示するとき、仮想化リストフレームワークは現在表示されているものよりも多くの行をプリレンダリングします。Offscreenを使用して、リスト内の表示アイテムよりも低い優先度で非表示の行をプリレンダリングできます。
- バックグラウンドコンテンツ:モーダルオーバーレイを表示するときなど、非表示にすることなくバックグラウンドでコンテンツの優先度を下げる関連機能も探求しています。
Transition Tracing
現在、Reactには2つのプロファイリングツールがあります。元のProfilerは、プロファイリングセッション内のすべてのコミットの概要を表示します。各コミットについて、レンダリングされたすべてのコンポーネントと、それらのレンダリングにかかった時間も表示します。また、React 18で導入されたTimeline Profilerのベータ版もあり、コンポーネントがいつ更新をスケジュールし、Reactがいつこれらの更新に取り組むかを表示します。
これらのプロファイラーは両方とも、開発者がコードのパフォーマンス問題を特定するのに役立ちます。開発者は、文脈から外れた個々の遅いコミットやコンポーネントについて知ることがそれほど有用ではないことがわかりました。実際に遅いコミットを引き起こす原因について知ることの方が有用です。そして、開発者は特定のインタラクション(例:ボタンクリック、初期ロード、ページナビゲーション)を追跡して、パフォーマンスの回帰を監視し、インタラクションが遅い理由とその修正方法を理解できるようにしたいと考えています。
私たちは以前、Interaction Tracing APIを作成してこの問題を解決しようとしましたが、インタラクションが遅い理由の追跡精度を低下させ、時にはインタラクションが終了しないという根本的な設計上の欠陥がありました。これらの問題のため、最終的にこのAPIを削除しました。
私たちは、これらの問題を解決するInteraction Tracing APIの新しいバージョン(startTransitionを介して開始されるため、暫定的にTransition Tracingと呼ばれています)に取り組んでいます。
New React Docs
昨年、新しいReactドキュメントウェブサイトのベータ版(後にreact.devとして出荷)を発表しました。新しい学習教材はHooksを最初に教え、新しい図表、イラスト、多くのインタラクティブな例とチャレンジがあります。
React 18のリリースに集中するためにその作業を一時中断しましたが、React 18がリリースされた今、新しいドキュメントの完成と出荷に積極的に取り組んでいます。
私たちは現在、エフェクトに関する詳細なセクションを書いています。これは、新しいReactユーザーと経験豊富なReactユーザーの両方にとって、より困難なトピックの1つであると聞いているためです。「Synchronizing with Effects」はシリーズで最初に公開されたページであり、今後数週間でさらに多くのページが公開される予定です。
エフェクトに関する詳細なセクションを書き始めたとき、多くの一般的なエフェクトパターンは、Reactに新しいプリミティブを追加することで簡素化できることがわかりました。useEvent RFCでその初期の考えを共有しました。これは現在初期研究段階にあり、まだアイデアを反復しています。
これまでのRFCに対するコミュニティのコメント、および進行中のドキュメント書き直しへのフィードバックと貢献に感謝しています。新しいウェブサイト実装に多くの改善を提出およびレビューしてくれたHarish Kumarに特に感謝したいと思います。
このブログ投稿をレビューしてくれたSophie Alpertに感謝します!