VIDEO LESSON
ReactのuseTransitionとuseDeferredValue:入力と一覧更新の優先度を分けるの解説動画
再生時間 7:12動画を別のタブで開く ↗
動画の字幕・文字起こしを読む
再生中の字幕を濃い黒で表示し、一番上に追従します。字幕の行を選ぶと、その位置から再生できます。
- 0:00こんにちは。
- 0:00リアクト入門の第六回です。
- 0:03今回は、ユーストランジションとユースディファードバリューで、入力と一覧更新の優先度を分ける方法を学びます。
- 0:11題材は、千二百件の商品から名前で絞り込む検索画面です。
- 0:16文字を打つたびに大きな一覧を作り直すと、入力欄の反応まで重く感じることがあります。
- 0:23そこで、入力はすぐに反映し、一覧の更新は後から追いついてもよい、と分けて考えます。
- 0:29これは処理そのものを速くする魔法ではありません。
- 0:33急ぐ更新と待てる更新を整理するための仕組みとして、一つずつ確認していきましょう。
- 0:40まず、二つのフックの使い分けです。
- 0:42自分でステート更新を実行する場面では、ユーストランジションを使います。
- 0:47更新をトランジションとして指定でき、保留中かどうかも分かります。
- 0:52一方、親から受け取った値など、更新処理を自分で持っていない場合は、ユースディファードバリューを使います。
- 0:59今の値を渡すと、描画が後から追従できる値が返ってきます。
- 1:03初回の描画では、通常は渡した値と同じ値が返ります。
- 1:07この記事では、リアクト十八でも使える一引数の形式で説明します。
- 1:11どちらを使うかは、更新の持ち主が誰かで決めると迷いません。
- 1:16共通の商品一覧、リザルツ・ティーエスエックスを作ります。
- 1:20商品は千二百件を用意し、名前で絞り込みます。
- 1:23件数が多いのは、描画の変化を観察しやすくするためです。
- 1:27受け取った検索語はトリムで前後の空白を取り除き、商品名に含まれるものだけをフィルターで残します。
- 1:34結果がゼロ件なら、該当する商品はありません、という案内を出し、一件以上あれば一覧を並べます。
- 1:41この部品はメモで包みます。
- 1:43親の入力値だけが変わり、一覧へ渡す検索語が同じ間は、再レンダーを省略しやすくするためです。
- 1:50実際の大規模な一覧では、ページ分割や仮想化も併せて検討してください。
- 1:55次に、ユーストランジションを使う検索、トランジションサーチを作ります。
- 2:00ここではステートが二つあります。
- 2:03入力欄に表示するインプットと、結果一覧に渡すクエリです。
- 2:07文字が入力されたら、まずインプットを通常の更新で即座に反映します。
- 2:12そして、クエリの更新だけをスタートトランジションで包みます。
- 2:16入力欄の更新までトランジションに入れないことがポイントです。
- 2:21ユーストランジションは、アイズペンディングとスタートトランジションを返します。
- 2:26アイズペンディングで、結果の更新が保留中かどうかを表示に使うことができます。
- 2:32スタートトランジションについて、誤解しやすい点を押さえます。
- 2:36スタートトランジションに渡した関数そのものが、後回しにされるわけではありません。
- 2:42その中で指定したステート更新が、割り込み可能な描画として扱われるのです。
- 2:47たとえば関数の中に重い同期ループを置いても、そのジャバスクリプトの処理が別スレッドへ移るわけではありません。
- 2:54止まっている原因が計算そのものなら、このフックだけでは解決しません。
- 2:59この記事の例では、同期的なステート更新だけを使っています。
- 3:03非同期の処理まで広げる場合は、使っているリアクトのバージョンごとの仕様を必ず確認してください。
- 3:09もう一方の例、ディファードサーチを作ります。
- 3:12こちらは入力用のステートがクエリの一つだけです。
- 3:16一覧に渡す値は、ユースディファードバリューから受け取るディファードクエリを使います。
- 3:22入力が変わった直後は、クエリとディファードクエリが異なる場合があります。
- 3:27その差をイズステイルとして取り出し、前の結果を表示している間であることを画面に伝えます。
- 3:34更新の実行を自分で包むユーストランジションと違い、こちらは値を渡して、遅れて追従する値を受け取る形です。
- 3:41親から受け取ったプロップスにも使えるのが、この形の利点です。
- 3:46遅れて更新される間は、前の結果が画面に残ることがあります。
- 3:50その状態を、利用者に分かる形で伝える工夫が大切です。
- 3:54ユーストランジションの例では、アイズペンディングを使って、結果を更新中です、
- 3:59という文章を表示し、一覧の透明度を少し下げます。
- 4:04ディファードの例では、イズステイルを使って、前の検索結果を表示しています、
- 4:08と知らせます。
- 4:11どちらも、エーリアビジーで更新中であることを支援技術にも伝えます。
- 4:16色だけに意味を持たせない点もポイントです。
- 4:20なお、端末が速く更新が軽い場合は、更新中の表示が目で確認できないこともあります。
- 4:26毎回、一定時間表示されるわけではありません。
- 4:29アプリ・ティーエスエックスに二つの検索を並べて、動作を確認します。
- 4:35初期状態では、どちらも千二百件が表示されます。
- 4:39商品千二百、と検索すると、結果は一件になります。
- 4:42存在しない語句では、ゼロ件の案内になります。
- 4:46片方を操作しても、もう片方の検索条件は変わりません。
- 4:50それぞれが独立したステートを持っているためです。
- 4:54入力を続けた後は、最終的に最新の入力に対応した結果が表示されることを確認してください。
- 5:01性能を比べるときは、同じ端末、同じデータ量、同じ操作で測定し、この例だけで常に速くなるとは結論づけないようにしましょう。
- 5:11よくある誤解の一つ目です。
- 5:13これらのフックは、デバウンスとは異なります。
- 5:16デバウンスは、入力が止まってから三百ミリ秒後に通信する、といった固定時間の待機の設計です。
- 5:23ユーストランジションもユースディファードバリューも、そのような時間待ちをする仕組みではありません。
- 5:31特に、ユースディファードバリューを使っただけでは、検索エーピーアイの通信回数は減りません。
- 5:38通信の回数を抑えたい場合は、デバウンスやキャッシュ、古いレスポンスの扱いを別途設計する必要があります。
- 5:45目的が違う仕組みを、名前の似たものとして混同しないようにしましょう。
- 5:51誤解の二つ目です。
- 5:52これらのフックは、シーピーユーの処理を別スレッドへ移すものではありません。
- 5:57大量データの同期計算そのものがボトルネックなら、計算方法の見直しや、ウェブワーカーなどが候補になります。
- 6:04ユーストランジションとユースディファードバリューが扱うのは、リアクトの更新をどういう優先度で進めるか、
- 6:08という問題です。
- 6:12使う順番も大切です。
- 6:13まずは基本フックで通常のステート更新を正しく理解し、入力の反応と一覧の更新が競合して困る場面で、
- 6:18初めて優先度の調整を検討してください。
- 6:22困っていない画面に、最初から入れるものではありません。
- 6:26まとめです。
- 6:27自分が実行するステート更新の優先度を下げたいときはユーストランジション、
- 6:33受け取った値を遅れて使いたいときはユースディファードバリュー、と更新の持ち主で選びます。
- 6:40どちらの場合も、更新中であることを文章などで利用者に伝える工夫をセットにしてください。
- 6:46今回、記事のコードそのままをタイプスクリプトの厳密な型チェックにかけて、
- 6:50エラーがないことを確認しました。
- 6:55絞り込みの計算もノード・ジェーエスで実行して確かめています。
- 6:59ブラウザー上で入力の反応を体感する確認は、実行環境の制約で未実施です。
- 7:05次回は、フラグメントやストリクトモード、サスペンスとレイジーを学びます。
- 7:10お疲れさまでした。
この動画で学べること
useTransitionとuseDeferredValueを検索画面のコードで比較。入力と結果更新の優先度、更新中の表示、デバウンスとの違いをReact 18対応の例で学びます。
解説記事・サンプルコードを読む:ReactのuseTransitionとuseDeferredValue:入力と一覧更新の優先度を分ける →