Closed13

React Conf 2021 メモ

Toshihisa TomatsuToshihisa Tomatsu

React 18 Keynote

https://youtu.be/FZ0cG47msEk

  • Streaming Server rendering の提供
  • React 18のリリース時点では Suspense for Data fetching はRelayだけサポートしてると思うけど、次のステップではLow level apiをサポートして、他のデータフェッチライブラリもすぐにサポートできるようにする
  • Concurrent renderingにより色々な新しい機能が可能になる
  • React 18にアップグレードしても、これまでと同じようにアプリは動く。そして新しい機能が徐々に利用可能になる。
    • 新しいレンダリングの仕組みは、React 18の新しい機能を使うコンポーネントでのみ有効になる
  • これからはConcurrent Modeではなく、Concurrent Featuresと呼ぶ
    • 一気に切り替わるわけじゃなくで段階的に導入していけるもの
  • Server Component
    • まだ実験中なのでStableビルドには含まれない
    • Next.jsと連携してて、実験的に試すことはできる
    • 18のどっかのマイナーバージョンで正式にリリースしたい
  • いまはReact NativeでConcurrent Renderingをサポートしてない
    • ただRNは基本的に非同期に設計されている
    • 同期を取る必要があるので、直感には反するけど、concurrentを可能にするために、新しいアーキテクチャとしてsynchroniesにする
    • この新しいアーキテクチャができるとReact 18がリリースできる
Toshihisa TomatsuToshihisa Tomatsu

React 18 for developers

https://youtu.be/ytudH8je5ko

  • Automatic batching
    • これまではstateを更新するたびに再レンダリングされていたが、batcingではハンドラーの最後に1度だけ再レンダリングするイメージ
    • 再レンダリングのパフォーマンスが改善する
    • opt out可能
  • Suspense on the server
    • これまではSSRがall or nothingだった
      • 特定のコンポーネントが遅いと、ページ全体が遅くなる
    • 遅い特定のコンポーネントでSuspenseを使うことで、読み込みを遅らせることができる
      • ローディング中のHTMLを先にクライアントに送っておいて、準備が整ったらストリーミングでHTMLを送る
      • JSが読み込まれる前に実行されるので、ユーザーが感じるレイテンシーが改善する
  • New APIs for app and library developers
    • Concurrent features
      • startTransition
      • useTransition
      • useDeferredValue
        • 緊急度が高くないコンポーネントのレンダリングを延期できる
    • mostly for libraries
      • useId
      • useSyncExternalStore
  • React 18へのアップデート方法
    • バージョンあげて、ReactDOM.renderをReactDOM.createRoor.render()にするだけ
Toshihisa TomatsuToshihisa Tomatsu

React Developer Tooling

https://youtu.be/oxDfrke8rZg

  • useStateの名前をsource mapからたどって表示可能にした
  • Profilerは便利だけど、React 18だと重要な情報に制限があったので、より必要な情報を提供するTimelineタブを追加
  • React Nativeでも色々出来ること増やしていく
Toshihisa TomatsuToshihisa Tomatsu

React without memo

https://youtu.be/lGEMwh32soc

  • ユーザーエクスペリエンスのためにmemo化するが、コードも読み辛くなるし考慮することが多い
  • ユーザーエクスペリエンスとDXを両立したい
  • React Forgetという自動でメモ化されたコードを生成するコンパイラを作ってる
Toshihisa TomatsuToshihisa Tomatsu

Re-introducing Relay

https://youtu.be/lhVGdErZuN4

  • Relayは他のフレームワークではできないことができる
  • Facebookや社内のツールでも利用している
  • 1つのQueryでページに必要なデータを取得することで、パフォーマンスがよくなる
  • コンポーネントが必要なデータを宣言する
    • コンパイル時に必要なクエリが生成される
  • Suspense for data fetchingはReactチームとRelayチームが協力して開発してる
    • ここが安定して最初に利用できるのは大きい
  • 全てのコンポーネントがサスペンドする可能性があるのに注意
  • deferディレクティブでクエリを複数のレスポンスに分割できる
    • 計算量の多いデータを遅らせたり
    • Suspenseとdeferディレクティブを調整するだけで、ユーザーに表示するロード状態を調整することができる
  • ページネーションも簡単に実現できる
  • Storeの更新忘れ
    • Relayはフラットまたは正規化されたストアを記録してる
      • 別のコンポーネントでも同じオブジェクトにアクセスしてるイメージ
    • コンポーネントがデータを読み出す時、アクセスしたデータを記録しておいて、ストアにデータが書き込まれるたびに、変更されたデータとコンポーネントがアクセスしたデータを比較する
    • データが実際に異なる場合のみコンポーネントが再レンダリングするので、高いパフォーマンスが維持できる
  • Pre generated instructions
    • コンパイラは各クエリの結果を効率的にストアに書き込むための処理も生成する
    • コンパイラはどういうデータがネットワークから返ってくるかを知っているので、コンパイル時に効率的なデータ構造を生成している
  • だんだんコンパイル速度が問題になってきたのでRustで書き直した
    • 平均5倍速くなった
  • 他にも新しい機能として
    • 何かしらの理由でフィールドが取得できないケースのために、nullチェックが必要
      • requiredディレクティブ
        • 必須フィールドが存在しない場合に、親オブジェクトを無効にしたりエラーを投げたりする
      • 1つのnullチェックで済む
Toshihisa TomatsuToshihisa Tomatsu

Streaming Server Rendering with Suspense

https://youtu.be/pj5N-Khihgc

  • React 18からのSSRはアプリの一部を非同期に返すことができる
  • Client Rendering
    • JSに全てのレンダリングの処理が含まれていて、JSのロードやデータの取得、コンポーネントのレンダリングなどをクライアントで行う
    • バンドルサイズが大きいと、サイトが表示されるまで時間がかかる
  • Server Rendering
    • リクエストがきたら、サーバーでアプリケーションに必要なデータを取得し、すべてのReactコンポーネントをHTMLにレンダリングする。HTMLがクライアントに送信されて、ブラウザでレンダリングされる
    • JSがロードされる前にサイトが表示されるので、Client Renderingよりもユーザーエクスペリエンスが改善されている
    • Server Renderingだけでは、十分ではない場合がある
      • HTMLの表示は早くなるけど、インタラクティブ可能になるにはJSを読み込んでHydrateが必要なので時間がかかる
  • 現状のServer Renderingは各プロセスでアプリケーション全体を1度に処理しているのが問題
    • データの取得
    • HTMLのレンダリング
    • JSの読み込み
    • Hydration
  • 問題1:ある1つの遅いコンポーネント(例:コメントコンポーネント)があった場合、全体が遅くなり、ユーザーは真っ白なページを見る時間が長くなる
    • 遅いコンポーネントをSSRから除外する選択肢もあるが、理想的では無い
      • そのコンポーネントがアプリケーションにとって重要なコンポーネントな場合
      • そのコンポーネントは最終的にはクライアントからデータを取得することになるので、処理を長引かせることになる(HTMLのレンダリングやJSの処理を待ってからデータを取得することになるので)
  • Hydration
    • ブラウザではReactが新しいDOMノードを作成するのではなく、コンポーネントツリーを走査して、SSRされたHTMLに対してイベントハンドラを設定する
  • 問題2:ある1つのJSコードが多いコンポーネント(例:コメントコンポーネント)があった場合、Hydrationを開始するには、全てのJSが読み込まれる必要がある
    • HTMLは返ってきてるので、ユーザーはコンテンツを見ることはできるが、Hydrationは行われていないので、操作はできない
    • Code SplittingでコメントコンポーネントのJSを別々に読み込ませる選択肢もあるが、理想的では無い
      • Hydrationの仕組み的に、重要なコンポーネントの場合でもSSRするHTMLにコメントコンポーネントを含めることができないことになる
  • 問題3:全てをHydrationが完了してないと、インタラクティブにならない
    • ある1つのコンポーネントの操作をしたいのに、Hydrationが完了しないと何もできない
  • React 18
    • 全て1度にまとめて処理するのではなく、作業を分割したり、非同期で行うことができるようになる
      • Suspenseコンポーネントで囲むだけで自動的に行われる
      • React 18のSuspenseはこれらを行うために、以下の2つの大きい機能が利用できるようになる
        • Streaming HTML
        • Selective Hydration
  • 問題になっていたコメントコンポーネントをSuspenseで囲むことで
    • データの取得に時間がかかっても、先に残りのHTMLをレンダリングして、コメントコンポーネントの準備ができたらコメントコンポーネントのHTMLを生成して、ストリームに送信する(Streaming HTML)
      • 最初のページレンダリングが早くなる
      • 取得中ということがわかるローディングUIにより、ユーザーエクスペリエンスが向上する
    • 遅いコンポーネントがあっても、先に残りのコンポーネントのHydrationを行い、コメントコンポーネントのJSが読み込まれると非同期にHydrationを行う(Selective Hydration)
      • すぐに操作可能になる
      • ローエンドのデバイスでHydrationに時間がかかっていて操作可能になるまでの時間が長くなる問題も改善する
  • 重いコンポーネントをSuspenseで囲むだけで、SSRのレンダリングプロセスの各段階でそれぞれ個別の非同期処理を行うことができる。囲まれていないコンポーネントは従来通り、まとめて1回で行う
  • 複数のコンポーネントで非同期にHydrationを行っていた場合、Hydration中であっても途中で一時停止して、ユーザーの操作があったコンポーネントのHydrationを優先的に行う。優先度の高いコンポーネントのHydrationが終わったら作業途中だったコンポーネントのHydrationに戻る
    • これによりよりユーザーエクスペリエンスを実現できる
Toshihisa TomatsuToshihisa Tomatsu

React 18 for External Store Libraries

https://youtu.be/oPfSC5bQPR8

  • React 18では、グローバルな状態の開発は慎重に行う必要がある
    • Opt-inでConcurrent renderingが行われる。ほとんどのライブラリはその影響を受けることは無いが、External Storeのライブラリは影響をうける
  • Tearing
    • ユーザーが見る視覚的な不整合
  • これまではレンダリング中にExternal Storeが変更される可能性が無かったので問題にならなかった
  • 例えば、External Storeにcountというstateがあった場合に、それを参照する二つのコンポーネント間でタイミングによって、更新された値とされる前の値がスクリーンに表示される
  • External Storeはsubscriptionを提供するので、Tearingは一時的なものでしかないが、許容できない場合は新しく追加される useSyncExternalStore Hooksが解決する
  • 移行をサポートするために、simを提供する「use-sync-external-store」パッケージを用意している
  • ライブラリのメンテなはuseSyncExternalStoreへの移行を検討するのがいい
Toshihisa TomatsuToshihisa Tomatsu

Building accessible components with React 18

https://youtu.be/dcm8fjBfro8

  • キーボードやスクリーンリーダーで操作できないコンボボックス
  • Ariakitというライブラリを使って、簡単にアクセシブルなコンポーネントにする
  • useDeferedValueを使うことで入力中にフォーカスが奪われないようにするテクニック
Toshihisa TomatsuToshihisa Tomatsu

React Native Desktop

https://youtu.be/9L4FFrvwJwY

  • Meta社のMessangerデスクトップアプリはElectron & Reactで作られていたが、ElectronのWebRTCの制限に悩まされて、最終的にはReact Native Desktopを選択した
  • 既存の資産を活かしつつ、段階的に移行していった
  • RNへの移行により、Windowsのプラットフォーム固有のコンポーネントやスタイル、システムテーマとの統合が可能になっりネイティブのメニューなど、そのプラットフォームのユーザーに馴染み深いものになった
  • RN Desktopでも高いDXが提供される
    • Fast Refreshなど
  • MicrosoftとReact Native
    • Officeアプリなどは幅広いプラットフォームで動作するアプリを提供しないといけない
    • Xboxアプリ
    • Power App
  • RN DesktokはRNのコアとの同期に注力している
    • Hermesをデフォルトで有効にしたり
    • 新しいアーキテクチャプラン
    • v66も同じバージョンで数日後にリリースした
Toshihisa TomatsuToshihisa Tomatsu

Accessible Japanese Form Components with React

https://youtu.be/S4a0QlsH0pU

  • 行政文書はとても複雑
    • 紙だと視覚に障害がある人にとってはさらに理解が難しい
  • 人事や労務の領域は様々な人が利用するので、アクセシビリティに配慮することが不可欠
  • ドメイン的に仕様も複雑なのでフォームに難しいロジックがある
  • SmartHR UIではアクセシブルなコンポーネントを提供して複数のプロダクトで利用
    • WCGAレベルAを推進して、テストもしてる
このスクラップは2022/08/24にクローズされました