1000行の一覧のうち1行だけ変えました。全部作り直すと画面への操作は2000回です。
前回と比べて違うところだけ直すと1回で済みます。ただし比較そのものに1000回かかります。
違いがあるところだけ触ります。ただし違いを見つけるための比較は、毎回全部にかかります。
Reactが画面に触るのは、前回との違いがあるところだけです。出典もそう述べています。
Reactは、描画のあいだに違いがある場合にのみ、画面上の節点を変更するという記述です。違いがなければ何もしません。
この効き目がどれくらいかを、差分の手続きをその場で実装して数えました。
1000行の一覧を用意し、並びは変えずに一部の行の中身だけを書き換えました。
一覧 1000行。並びは変えず、一部の行の中身だけを書き換える
画面への操作=節点を作る、消す、文字を差し替える
変えた行 全部作り直す(操作) 差分をとる(比べた回数) 差分をとる(操作) 操作の比
1行 2000回 1000回 1回 2000.0倍
10行 2000回 1000回 10回 200.0倍
100行 2000回 1000回 100回 20.0倍
1000行 2000回 1000回 1000回 2.0倍
1行だけなら2000回が1回になります。差は2000倍です。
全行を変える場合は2.0倍まで縮みます。それでも作り直しより少ないのは、節点を消して作り直さずに文字だけ差し替えるためです。
真ん中の列はどの行でも1000回です。1行しか変えなくても、全部を見に行きます。
つまり画面への操作は減っても、計算は減っていません。差分をとる方式が有利なのは、画面への操作のほうが高くつくためです。
比較を減らしたいなら、比べる範囲を先に絞るしかありません。変わった部分だけを比べる仕組みは、この計測の外にあります。
状態が変わると関数が呼ばれ、前回と比べてから画面に触る。
React only changes the DOM nodes if there's a difference between renders.原文React 公式ドキュメント「Render and Commit」 この内容の有効期限2027-02-18
位置で突き合わせると、1行ずれた時点で以降が全部別物に見えます。目印があれば1回です。
Reactは一覧の要素を目印で追います。出典は並び順を目印にすると、しばしば分かりにくく紛らわしい不具合につながると明言しています。
何が起きるかを数えました。中身は変えず、並びのほうだけを変えます。
一覧 1000行。並びのほうを変える。中身は変えない 変え方 位置で突き合わせる 目印で突き合わせる 比 先頭に1行足す 1001回 1回 1001.0倍 末尾に1行足す 1回 1回 1.0倍 先頭の1行を消す 1000回 1回 1000.0倍 前後を入れ替える 1000回 500回 2.0倍 並びを逆にする 1000回 999回 1.0倍
先頭に1行足すと1001回です。1行増えただけで、以降の1000行が全部ずれます。
末尾なら1回です。同じ「1行足す」でも、位置によって1000倍違います。
最下行を見てください。並びを逆にすると、目印があっても999回かかります。
本当に全部の位置が変わっているので、これは減りません。目印は、変わっていないものを変わっていないと分かるための仕組みです。
だから効くのは足す・消す・一部を動かす場面に限られます。全部が動く場面では差が出ません。
位置で突き合わせると、先頭をいじった時点で全行が別物になる。
Index as a key often leads to subtle and confusing bugs.原文React 公式ドキュメント「Rendering Lists」 この内容の有効期限2027-02-18
画面全体を作り直しているように見えて、実際に呼ばれる関数は限られています。
Reactで関数が呼ばれる条件は決まっています。出典は2回目以降の描画では、Reactは、その描画を引き起こした状態更新を持つ関数部品を呼ぶと述べています。
起点はその部品です。そこから下へたどった範囲が呼び直されます。
3番目が効きます。状態を下のほうに置くほど、呼び直される範囲が狭くなります。
逆に、一番上に状態を集めると全部が呼び直されます。この場合でも画面への操作は差分だけですが、比較の1000回にあたる手間は全体にかかります。
状態は使う部品の共通の親まで上げて、そこで止めるのが基本です。それより上に置く理由はありません。
並べ方そのものの話はUI・UX設計の記事で扱っています。ここでの要点は、状態の位置が呼び直しの範囲を決めるという1点です。
この計測は実際のブラウザを使っていません。木構造と差分の手続きをその場で実装し、画面への操作の回数を数えたものです。実際の所要時間は、操作1回あたりの重さや配置の計算に左右されるので、ここでの回数比がそのまま時間比になるわけではありません。ここで見せているのは、変える量が少ないほど差分の効き目が大きくなり、目印がないとその効き目が消えるという関係です。
For subsequent renders, React will call the function component whose state update triggered the render.原文React 公式ドキュメント「Render and Commit」 この内容の有効期限2027-02-18
同じ課題を持つ会社にとって、動いている設定は「作る時間」を買えるということです。ServiceDockは自作のワークフローやテンプレートを出品できるマーケットプレイスです。手数料や出品の流れは出品者向けページにまとまっています。
出品の仕組みを見る