WEBVTT

1
00:00:00.000 --> 00:00:00.991
こんにちは。

2
00:00:00.991 --> 00:00:03.138
リアクト入門の第六回です。

3
00:00:03.138 --> 00:00:11.893
今回は、ユーストランジションとユースディファードバリューで、入力と一覧更新の優先度を分ける方法を学びます。

4
00:00:11.893 --> 00:00:16.352
題材は、千二百件の商品から名前で絞り込む検索画面です。

5
00:00:16.352 --> 00:00:23.125
文字を打つたびに大きな一覧を作り直すと、入力欄の反応まで重く感じることがあります。

6
00:00:23.125 --> 00:00:29.897
そこで、入力はすぐに反映し、一覧の更新は後から追いついてもよい、と分けて考えます。

7
00:00:29.897 --> 00:00:33.861
これは処理そのものを速くする魔法ではありません。

8
00:00:33.861 --> 00:00:40.468
急ぐ更新と待てる更新を整理するための仕組みとして、一つずつ確認していきましょう。

9
00:00:40.468 --> 00:00:42.895
まず、二つのフックの使い分けです。

10
00:00:42.895 --> 00:00:47.892
自分でステート更新を実行する場面では、ユーストランジションを使います。

11
00:00:47.892 --> 00:00:52.460
更新をトランジションとして指定でき、保留中かどうかも分かります。

12
00:00:52.460 --> 00:00:59.884
一方、親から受け取った値など、更新処理を自分で持っていない場合は、ユースディファードバリューを使います。

13
00:00:59.884 --> 00:01:03.881
今の値を渡すと、描画が後から追従できる値が返ってきます。

14
00:01:03.881 --> 00:01:07.450
初回の描画では、通常は渡した値と同じ値が返ります。

15
00:01:07.450 --> 00:01:11.876
この記事では、リアクト十八でも使える一引数の形式で説明します。

16
00:01:11.876 --> 00:01:16.016
どちらを使うかは、更新の持ち主が誰かで決めると迷いません。

17
00:01:16.016 --> 00:01:20.230
共通の商品一覧、リザルツ・ティーエスエックスを作ります。

18
00:01:20.230 --> 00:01:23.541
商品は千二百件を用意し、名前で絞り込みます。

19
00:01:23.541 --> 00:01:27.604
件数が多いのは、描画の変化を観察しやすくするためです。

20
00:01:27.604 --> 00:01:34.828
受け取った検索語はトリムで前後の空白を取り除き、商品名に含まれるものだけをフィルターで残します。

21
00:01:34.828 --> 00:01:41.751
結果がゼロ件なら、該当する商品はありません、という案内を出し、一件以上あれば一覧を並べます。

22
00:01:41.751 --> 00:01:43.707
この部品はメモで包みます。

23
00:01:43.707 --> 00:01:50.479
親の入力値だけが変わり、一覧へ渡す検索語が同じ間は、再レンダーを省略しやすくするためです。

24
00:01:50.479 --> 00:01:55.596
実際の大規模な一覧では、ページ分割や仮想化も併せて検討してください。

25
00:01:55.596 --> 00:02:00.785
次に、ユーストランジションを使う検索、トランジションサーチを作ります。

26
00:02:00.785 --> 00:02:03.158
ここではステートが二つあります。

27
00:02:03.158 --> 00:02:07.309
入力欄に表示するインプットと、結果一覧に渡すクエリです。

28
00:02:07.309 --> 00:02:12.202
文字が入力されたら、まずインプットを通常の更新で即座に反映します。

29
00:02:12.202 --> 00:02:16.650
そして、クエリの更新だけをスタートトランジションで包みます。

30
00:02:16.650 --> 00:02:21.098
入力欄の更新までトランジションに入れないことがポイントです。

31
00:02:21.098 --> 00:02:26.880
ユーストランジションは、アイズペンディングとスタートトランジションを返します。

32
00:02:26.880 --> 00:02:32.514
アイズペンディングで、結果の更新が保留中かどうかを表示に使うことができます。

33
00:02:32.514 --> 00:02:36.645
スタートトランジションについて、誤解しやすい点を押さえます。

34
00:02:36.645 --> 00:02:42.154
スタートトランジションに渡した関数そのものが、後回しにされるわけではありません。

35
00:02:42.154 --> 00:02:47.111
その中で指定したステート更新が、割り込み可能な描画として扱われるのです。

36
00:02:47.111 --> 00:02:54.548
たとえば関数の中に重い同期ループを置いても、そのジャバスクリプトの処理が別スレッドへ移るわけではありません。

37
00:02:54.548 --> 00:02:59.230
止まっている原因が計算そのものなら、このフックだけでは解決しません。

38
00:02:59.230 --> 00:03:03.224
この記事の例では、同期的なステート更新だけを使っています。

39
00:03:03.224 --> 00:03:09.696
非同期の処理まで広げる場合は、使っているリアクトのバージョンごとの仕様を必ず確認してください。

40
00:03:09.696 --> 00:03:12.915
もう一方の例、ディファードサーチを作ります。

41
00:03:12.915 --> 00:03:16.427
こちらは入力用のステートがクエリの一つだけです。

42
00:03:16.427 --> 00:03:22.572
一覧に渡す値は、ユースディファードバリューから受け取るディファードクエリを使います。

43
00:03:22.572 --> 00:03:27.840
入力が変わった直後は、クエリとディファードクエリが異なる場合があります。

44
00:03:27.840 --> 00:03:34.278
その差をイズステイルとして取り出し、前の結果を表示している間であることを画面に伝えます。

45
00:03:34.278 --> 00:03:41.886
更新の実行を自分で包むユーストランジションと違い、こちらは値を渡して、遅れて追従する値を受け取る形です。

46
00:03:41.886 --> 00:03:46.276
親から受け取ったプロップスにも使えるのが、この形の利点です。

47
00:03:46.276 --> 00:03:50.839
遅れて更新される間は、前の結果が画面に残ることがあります。

48
00:03:50.839 --> 00:03:54.931
その状態を、利用者に分かる形で伝える工夫が大切です。

49
00:03:54.931 --> 00:03:59.809
ユーストランジションの例では、アイズペンディングを使って、結果を更新中です、

50
00:03:59.809 --> 00:04:04.687
という文章を表示し、一覧の透明度を少し下げます。

51
00:04:04.687 --> 00:04:08.149
ディファードの例では、イズステイルを使って、前の検索結果を表示しています、

52
00:04:08.149 --> 00:04:11.610
と知らせます。

53
00:04:11.610 --> 00:04:16.803
どちらも、エーリアビジーで更新中であることを支援技術にも伝えます。

54
00:04:16.803 --> 00:04:20.108
色だけに意味を持たせない点もポイントです。

55
00:04:20.108 --> 00:04:26.402
なお、端末が速く更新が軽い場合は、更新中の表示が目で確認できないこともあります。

56
00:04:26.402 --> 00:04:29.864
毎回、一定時間表示されるわけではありません。

57
00:04:29.864 --> 00:04:35.266
アプリ・ティーエスエックスに二つの検索を並べて、動作を確認します。

58
00:04:35.266 --> 00:04:39.032
初期状態では、どちらも千二百件が表示されます。

59
00:04:39.032 --> 00:04:42.961
商品千二百、と検索すると、結果は一件になります。

60
00:04:42.961 --> 00:04:46.562
存在しない語句では、ゼロ件の案内になります。

61
00:04:46.562 --> 00:04:50.819
片方を操作しても、もう片方の検索条件は変わりません。

62
00:04:50.819 --> 00:04:54.748
それぞれが独立したステートを持っているためです。

63
00:04:54.748 --> 00:05:01.787
入力を続けた後は、最終的に最新の入力に対応した結果が表示されることを確認してください。

64
00:05:01.787 --> 00:05:11.610
性能を比べるときは、同じ端末、同じデータ量、同じ操作で測定し、この例だけで常に速くなるとは結論づけないようにしましょう。

65
00:05:11.610 --> 00:05:13.593
よくある誤解の一つ目です。

66
00:05:13.593 --> 00:05:16.949
これらのフックは、デバウンスとは異なります。

67
00:05:16.949 --> 00:05:23.813
デバウンスは、入力が止まってから三百ミリ秒後に通信する、といった固定時間の待機の設計です。

68
00:05:23.813 --> 00:05:31.288
ユーストランジションもユースディファードバリューも、そのような時間待ちをする仕組みではありません。

69
00:05:31.288 --> 00:05:38.152
特に、ユースディファードバリューを使っただけでは、検索エーピーアイの通信回数は減りません。

70
00:05:38.152 --> 00:05:45.932
通信の回数を抑えたい場合は、デバウンスやキャッシュ、古いレスポンスの扱いを別途設計する必要があります。

71
00:05:45.932 --> 00:05:51.118
目的が違う仕組みを、名前の似たものとして混同しないようにしましょう。

72
00:05:51.118 --> 00:05:52.341
誤解の二つ目です。

73
00:05:52.341 --> 00:05:57.368
これらのフックは、シーピーユーの処理を別スレッドへ移すものではありません。

74
00:05:57.368 --> 00:06:04.433
大量データの同期計算そのものがボトルネックなら、計算方法の見直しや、ウェブワーカーなどが候補になります。

75
00:06:04.433 --> 00:06:08.441
ユーストランジションとユースディファードバリューが扱うのは、リアクトの更新をどういう優先度で進めるか、

76
00:06:08.441 --> 00:06:12.449
という問題です。

77
00:06:12.449 --> 00:06:13.808
使う順番も大切です。

78
00:06:13.808 --> 00:06:18.359
まずは基本フックで通常のステート更新を正しく理解し、入力の反応と一覧の更新が競合して困る場面で、

79
00:06:18.359 --> 00:06:22.911
初めて優先度の調整を検討してください。

80
00:06:22.911 --> 00:06:26.579
困っていない画面に、最初から入れるものではありません。

81
00:06:26.579 --> 00:06:27.521
まとめです。

82
00:06:27.521 --> 00:06:33.803
自分が実行するステート更新の優先度を下げたいときはユーストランジション、

83
00:06:33.803 --> 00:06:40.085
受け取った値を遅れて使いたいときはユースディファードバリュー、と更新の持ち主で選びます。

84
00:06:40.085 --> 00:06:46.838
どちらの場合も、更新中であることを文章などで利用者に伝える工夫をセットにしてください。

85
00:06:46.838 --> 00:06:50.921
今回、記事のコードそのままをタイプスクリプトの厳密な型チェックにかけて、

86
00:06:50.921 --> 00:06:55.004
エラーがないことを確認しました。

87
00:06:55.004 --> 00:06:59.715
絞り込みの計算もノード・ジェーエスで実行して確かめています。

88
00:06:59.715 --> 00:07:05.212
ブラウザー上で入力の反応を体感する確認は、実行環境の制約で未実施です。

89
00:07:05.212 --> 00:07:10.866
次回は、フラグメントやストリクトモード、サスペンスとレイジーを学びます。

90
00:07:10.866 --> 00:07:12.279
お疲れさまでした。
