RelayHubPublicationへの投稿⚡Reactで実装したフォームのパフォーマンスが問題になるのはなぜかanatoo2024/01/15に公開2024/01/163件JavaScriptReactperformancefrontendformtechRelayHubPublicationRelayHub(relayhub.jp)のエンジニアリングブログです。Discussionsmikitky2024/01/16普通にcontrolled componentでやってみてパフォーマンスの問題が出ることって多いのでしょうか。今ぱっと実験した限り、その「いわゆる愚直な方式」で毎キーストローク全部を再レンダーした場合、仰るようなパフォーマンス問題が本当に「顕在化」するのはinputを数千個以上並べたときです。別に input や textarea に限った話ではなく、何らの最適化をしない場合は毎秒DOM要素が数万個といったレベルの処理にReactの限界が存在するのは確かです。でも私はinputを100個並べたフォームすらまず作りませんので、「フォームのパフォーマンスが問題になりやすい」などと現実に感じたことは一度もありません。 この MyForm のような、せいぜい一度に数十要素といったレベルでの更新であればReactは十分に速く、10msどころか1msだろうと楽々クリアしますし、むしろそれがReactの本分そのものとも言えるので、いったいみんなは何を心配しているのだろう…と感じてしまっています。 記事中では一部で「潜在的問題」と断っている部分もありつつ、現実にパフォーマンスの問題が出やすいかのような書き方がベースになっています。世の開発者はそんなにしょっちゅう1コンポーネントで数千ものinputを同時に扱っているのでしょうか。controlledであることで具体的にパフォーマンスに問題が出る一般的な例があるなら知りたいです。(仮にあったとしてもそんな複雑なフォームはcontrolledのままで改善する方針を考えた方がバグが少なくなりそうですが…) anatoo2024/01/16smikitkyさん、おっしゃるとおりで、例で示した程度のコードでは現実的には全く問題にならないです。ただ、Controlled Inputを使っていてキー入力が詰まってしまうようなコードというのは、僕が遭遇したものだと、画面にたくさんのデータを表示するデータシートがフォームの状態に依存している場合や、コンポーネントの中で単純に重たい処理をしている場合などがそうでした。input要素の数が問題なのではなく単純にキー入力のたびに行われる再レンダリングのオーバーヘッドが大きくなると問題になるということですね。Controlledであっても個別に最適化すればそれは問題ないと思います。 smikitky2024/01/16 画面にたくさんのデータを表示するデータシートがフォームの状態に依存している A欄の入力内容に応じて重たい集計結果やフィルタリングの結果をリアルタイムに反映しないといけない上に、無関係のB欄やC欄に1文字タイプするだけでもその重い処理がなぜか毎回走る…みたいな状況でしょうか。本来は useMemo や useDeferredValue の出番のような気がしますし、何なら単なるデバウンスも効きます。そこで「B欄やC欄をuncontrolledにして切り離せばいい」という発想は自分はしたことがなかったのですが、確かにそれも解決法ではあるのかもしれませんね。 コンポーネントの中で単純に重たい処理をしている フォームの項目中にカスタムのデートピッカー等が大量にあるような場合でしょうか。複雑で多機能なフォームほどcontrolledにして情報源 (source of truth) をJavaScript内に集中させるメリットを享受できるので memo とか使ってちゃんと最適化すべし…と思っていたのですが、最近のフォーム系ライブラリがその辺もうまいことやってくれるならそれもアリなのかもという気がしてきました。ありがとうございました。 返信を追加
smikitky2024/01/16普通にcontrolled componentでやってみてパフォーマンスの問題が出ることって多いのでしょうか。今ぱっと実験した限り、その「いわゆる愚直な方式」で毎キーストローク全部を再レンダーした場合、仰るようなパフォーマンス問題が本当に「顕在化」するのはinputを数千個以上並べたときです。別に input や textarea に限った話ではなく、何らの最適化をしない場合は毎秒DOM要素が数万個といったレベルの処理にReactの限界が存在するのは確かです。でも私はinputを100個並べたフォームすらまず作りませんので、「フォームのパフォーマンスが問題になりやすい」などと現実に感じたことは一度もありません。 この MyForm のような、せいぜい一度に数十要素といったレベルでの更新であればReactは十分に速く、10msどころか1msだろうと楽々クリアしますし、むしろそれがReactの本分そのものとも言えるので、いったいみんなは何を心配しているのだろう…と感じてしまっています。 記事中では一部で「潜在的問題」と断っている部分もありつつ、現実にパフォーマンスの問題が出やすいかのような書き方がベースになっています。世の開発者はそんなにしょっちゅう1コンポーネントで数千ものinputを同時に扱っているのでしょうか。controlledであることで具体的にパフォーマンスに問題が出る一般的な例があるなら知りたいです。(仮にあったとしてもそんな複雑なフォームはcontrolledのままで改善する方針を考えた方がバグが少なくなりそうですが…) anatoo2024/01/16smikitkyさん、おっしゃるとおりで、例で示した程度のコードでは現実的には全く問題にならないです。ただ、Controlled Inputを使っていてキー入力が詰まってしまうようなコードというのは、僕が遭遇したものだと、画面にたくさんのデータを表示するデータシートがフォームの状態に依存している場合や、コンポーネントの中で単純に重たい処理をしている場合などがそうでした。input要素の数が問題なのではなく単純にキー入力のたびに行われる再レンダリングのオーバーヘッドが大きくなると問題になるということですね。Controlledであっても個別に最適化すればそれは問題ないと思います。 smikitky2024/01/16 画面にたくさんのデータを表示するデータシートがフォームの状態に依存している A欄の入力内容に応じて重たい集計結果やフィルタリングの結果をリアルタイムに反映しないといけない上に、無関係のB欄やC欄に1文字タイプするだけでもその重い処理がなぜか毎回走る…みたいな状況でしょうか。本来は useMemo や useDeferredValue の出番のような気がしますし、何なら単なるデバウンスも効きます。そこで「B欄やC欄をuncontrolledにして切り離せばいい」という発想は自分はしたことがなかったのですが、確かにそれも解決法ではあるのかもしれませんね。 コンポーネントの中で単純に重たい処理をしている フォームの項目中にカスタムのデートピッカー等が大量にあるような場合でしょうか。複雑で多機能なフォームほどcontrolledにして情報源 (source of truth) をJavaScript内に集中させるメリットを享受できるので memo とか使ってちゃんと最適化すべし…と思っていたのですが、最近のフォーム系ライブラリがその辺もうまいことやってくれるならそれもアリなのかもという気がしてきました。ありがとうございました。 返信を追加
anatoo2024/01/16smikitkyさん、おっしゃるとおりで、例で示した程度のコードでは現実的には全く問題にならないです。ただ、Controlled Inputを使っていてキー入力が詰まってしまうようなコードというのは、僕が遭遇したものだと、画面にたくさんのデータを表示するデータシートがフォームの状態に依存している場合や、コンポーネントの中で単純に重たい処理をしている場合などがそうでした。input要素の数が問題なのではなく単純にキー入力のたびに行われる再レンダリングのオーバーヘッドが大きくなると問題になるということですね。Controlledであっても個別に最適化すればそれは問題ないと思います。
smikitky2024/01/16 画面にたくさんのデータを表示するデータシートがフォームの状態に依存している A欄の入力内容に応じて重たい集計結果やフィルタリングの結果をリアルタイムに反映しないといけない上に、無関係のB欄やC欄に1文字タイプするだけでもその重い処理がなぜか毎回走る…みたいな状況でしょうか。本来は useMemo や useDeferredValue の出番のような気がしますし、何なら単なるデバウンスも効きます。そこで「B欄やC欄をuncontrolledにして切り離せばいい」という発想は自分はしたことがなかったのですが、確かにそれも解決法ではあるのかもしれませんね。 コンポーネントの中で単純に重たい処理をしている フォームの項目中にカスタムのデートピッカー等が大量にあるような場合でしょうか。複雑で多機能なフォームほどcontrolledにして情報源 (source of truth) をJavaScript内に集中させるメリットを享受できるので memo とか使ってちゃんと最適化すべし…と思っていたのですが、最近のフォーム系ライブラリがその辺もうまいことやってくれるならそれもアリなのかもという気がしてきました。ありがとうございました。
Discussion
普通にcontrolled componentでやってみてパフォーマンスの問題が出ることって多いのでしょうか。今ぱっと実験した限り、その「いわゆる愚直な方式」で毎キーストローク全部を再レンダーした場合、仰るようなパフォーマンス問題が本当に「顕在化」するのはinputを数千個以上並べたときです。別に input や textarea に限った話ではなく、何らの最適化をしない場合は毎秒DOM要素が数万個といったレベルの処理にReactの限界が存在するのは確かです。でも私はinputを100個並べたフォームすらまず作りませんので、「フォームのパフォーマンスが問題になりやすい」などと現実に感じたことは一度もありません。
この
MyFormのような、せいぜい一度に数十要素といったレベルでの更新であればReactは十分に速く、10msどころか1msだろうと楽々クリアしますし、むしろそれがReactの本分そのものとも言えるので、いったいみんなは何を心配しているのだろう…と感じてしまっています。記事中では一部で「潜在的問題」と断っている部分もありつつ、現実にパフォーマンスの問題が出やすいかのような書き方がベースになっています。世の開発者はそんなにしょっちゅう1コンポーネントで数千ものinputを同時に扱っているのでしょうか。controlledであることで具体的にパフォーマンスに問題が出る一般的な例があるなら知りたいです。(仮にあったとしてもそんな複雑なフォームはcontrolledのままで改善する方針を考えた方がバグが少なくなりそうですが…)
smikitkyさん、おっしゃるとおりで、例で示した程度のコードでは現実的には全く問題にならないです。ただ、Controlled Inputを使っていてキー入力が詰まってしまうようなコードというのは、僕が遭遇したものだと、画面にたくさんのデータを表示するデータシートがフォームの状態に依存している場合や、コンポーネントの中で単純に重たい処理をしている場合などがそうでした。input要素の数が問題なのではなく単純にキー入力のたびに行われる再レンダリングのオーバーヘッドが大きくなると問題になるということですね。Controlledであっても個別に最適化すればそれは問題ないと思います。
A欄の入力内容に応じて重たい集計結果やフィルタリングの結果をリアルタイムに反映しないといけない上に、無関係のB欄やC欄に1文字タイプするだけでもその重い処理がなぜか毎回走る…みたいな状況でしょうか。本来は
useMemoやuseDeferredValueの出番のような気がしますし、何なら単なるデバウンスも効きます。そこで「B欄やC欄をuncontrolledにして切り離せばいい」という発想は自分はしたことがなかったのですが、確かにそれも解決法ではあるのかもしれませんね。フォームの項目中にカスタムのデートピッカー等が大量にあるような場合でしょうか。複雑で多機能なフォームほどcontrolledにして情報源 (source of truth) をJavaScript内に集中させるメリットを享受できるので
memoとか使ってちゃんと最適化すべし…と思っていたのですが、最近のフォーム系ライブラリがその辺もうまいことやってくれるならそれもアリなのかもという気がしてきました。ありがとうございました。