Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
React Hook Form はどのように再レンダリングを最適化しているのか?
Search
Sponsored
·
Ship Features Fearlessly
Turn features on and off without deploys. Used by thousands of Ruby developers.
→
Kotaro Sugawara
October 29, 2021
Technology
9
6.6k
React Hook Form はどのように再レンダリングを最適化しているのか?
【READYFOR×コミューン】業務に活かせるReact LT & 座談会
https://readyfor.connpass.com/event/224586/
Kotaro Sugawara
October 29, 2021
Tweet
Share
More Decks by Kotaro Sugawara
See All by Kotaro Sugawara
OpenAPI Generator と TypeScript による型安全なスキーマ駆動開発
kotarella1110
4
49k
Other Decks in Technology
See All in Technology
AIと新時代を切り拓く。これからのSREとメルカリIBISの挑戦
0gm
0
660
GitHub Issue Templates + Coding Agentで簡単みんなでIaC/Easy IaC for Everyone with GitHub Issue Templates + Coding Agent
aeonpeople
1
140
toCプロダクトにおけるAI機能開発のしくじりと学び / ai-product-failures-and-learnings
rince
6
5.5k
ClickHouseはどのように大規模データを活用したAIエージェントを全社展開しているのか
mikimatsumoto
0
160
MCPでつなぐElasticsearchとLLM - 深夜の障害対応を楽にしたい / Bridging Elasticsearch and LLMs with MCP
sashimimochi
0
130
AI時代、1年目エンジニアの悩み
jin4
1
150
Contract One Engineering Unit 紹介資料
sansan33
PRO
0
13k
オープンウェイトのLLMリランカーを契約書で評価する / searchtechjp
sansan_randd
3
630
IaaS/SaaS管理における SREの実践 - SRE Kaigi 2026
bbqallstars
4
1.5k
Amazon Bedrock AgentCore 認証・認可入門
hironobuiga
2
500
2人で作ったAIダッシュボードが、開発組織の次の一手を照らした話― Cursor × SpecKit × 可視化の実践 ― Qiita AI Summit
noalisaai
1
370
SREのプラクティスを用いた3領域同時 マネジメントへの挑戦 〜SRE・情シス・セキュリティを統合した チーム運営術〜
coconala_engineer
2
550
Featured
See All Featured
Why You Should Never Use an ORM
jnunemaker
PRO
61
9.7k
Agile that works and the tools we love
rasmusluckow
331
21k
The Power of CSS Pseudo Elements
geoffreycrofte
80
6.1k
The Illustrated Guide to Node.js - THAT Conference 2024
reverentgeek
0
250
How to Talk to Developers About Accessibility
jct
2
120
The State of eCommerce SEO: How to Win in Today's Products SERPs - #SEOweek
aleyda
2
9.5k
SEO in 2025: How to Prepare for the Future of Search
ipullrank
3
3.3k
[RailsConf 2023] Rails as a piece of cake
palkan
59
6.3k
brightonSEO & MeasureFest 2025 - Christian Goodrich - Winning strategies for Black Friday CRO & PPC
cargoodrich
3
95
A Modern Web Designer's Workflow
chriscoyier
698
190k
From Legacy to Launchpad: Building Startup-Ready Communities
dugsong
0
140
The World Runs on Bad Software
bkeepers
PRO
72
12k
Transcript
1 React Hook Form はどのように再レンダリングを最適化しているのか? 2021/10/29 菅原 弘太郎
2 自己紹介 Kotaro Sugawara @kotarella1110 • エンジニアリング本部/システム基盤部 • フロントエンドエンジニア •
2020年11月入社(もう少しで入社して一年 🎉) • 岩手県在住のリモートワーカー • React Hook Form のメンバー #ReactLT
3 本日お話しすること • React Hook Form とは? • React のパフォーマンス最適化
• React Hook Form はどのように再レンダリングを最適化しているのか? #ReactLT
4 React Hook Form とは? #ReactLT
5 React Hook Form とは? 非制御コンポーネントをベースに構築されたフォームバリデーション用の React フックライブラリ #ReactLT
6 React Hook Form とは? React Hook Form のコード例 #ReactLT
7 React Hook Form とは? 特徴 • パフォーマンス、UX、DX を念頭に置いて構築 •
非制御フォームバリデーション • UI ライブラリと簡単に統合可能(Controlled Components もサポート) • パッケージのサイズが小さく、依存関係がない • HTML 標準のバリデーション(Constraint Validation API) • スキーマベースのバリデーションをサポート(Yup、Zod、Superstruct など) #ReactLT
8 React Hook Form とは? 特徴 • パフォーマンス、UX、DX を念頭に置いて構築 •
非制御フォームバリデーション • UI ライブラリと簡単に統合可能(Controlled Components もサポート) • パッケージのサイズが小さく、依存関係がない • HTML 標準のバリデーション(Constraint Validation API) • スキーマベースのバリデーションをサポート(Yup、Zod、Superstruct など) #ReactLT
9 React のパフォーマンス最適化 #ReactLT
10 React のパフォーマンス最適化 React のパフォーマンス最適化において重要なこと 無駄な計算と再レンダリングを抑える #ReactLT
11 React のパフォーマンス最適化 パフォーマンスの最適化手法 • useCallback/useMemo による関数と値のメモ化 ◦ 再レンダリング・値の不要な再計算をスキップ •
React.memo によるコンポーネントのメモ化 ◦ useCallback/useMemo と併用することで、コンポーネントの再レンダリングを スキップ • Context の使用 ◦ Provider と Consumer(Context から値を取得するコンポーネント)間の中間コ ンポーネントの再レンダリングをスキップ #ReactLT
12 React のパフォーマンス最適化 Context の分割について Provider 配下の全ての Consumer は、Provider の
value プロパティが変 更されるたびに再レンダリングが発生 します。 これは機能的に問題はありませんが、 不要な再レンダリングが発生してしまう ケースがあります。 Provider Consumer Consumer #ReactLT
13 Context の分割について React のパフォーマンス最適化 例えば右の図のように、状態(可変)と それを更新する関数(不変)を value に 渡しているケースです。ConsumerA
で は Context から state のみを取得し、 ConsumerB では setState のみを取 得します。 value={{ state, setState }} Provider ConsumerB ConsumerA state setState #ReactLT
14 Context の分割について React のパフォーマンス最適化 setState が呼び出される度に Provider では state
が更新され value プロパティに変更が発生します。 value={{ state, setState }} Provider ConsumerB ConsumerA state setState state setState(value) の呼び出し #ReactLT
15 Context の分割について React のパフォーマンス最適化 value プロパティに変更があるため、 state を Context
から取得している ConsumerA だけでなく ConsumerB も 再レンダリングが発生してしまいます。 value={{ state, setState }} Provider ConsumerB ConsumerA state setState state setState(value) の呼び出し #ReactLT
16 Context の分割について React のパフォーマンス最適化 この不要な再レンダリングを排除するため には Context を分割する必要があります。 右の図のように分割することで、
ProviderB の value プロパティは不変にな るため、ConsumerB は state が更新され ても再レンダリングが発生しなくなります。 value={{ setState }} ProviderB ConsumerB ConsumerA value={{ state }} state setState ProviderA setState(value) の呼び出し state #ReactLT
17 Context の分割について React のパフォーマンス最適化 とはいえ、Consumer 側で再レンダリングを細かく制御したい場合など Context を単純に分割できないケースがあります。 例えば、Redux
の useSelector のように、selector 関数が返す値に更新が あった場合のみ再レンダリングを行うといったことを Context のみで実現するこ とは難しいです。 #ReactLT
18 React Hook Form はどのように再レンダリングを最適化してるのか? #ReactLT
19 Subscription ベースの状態管理 #ReactLT
20 Subscription ベースの状態管理 Subscription ベースの状態管理を採用 • React Hook Form は再レンダリングを細かく制御するために
Redux や Recoil などと同じように Subscription ベースの状態管理を採用 • これにより、useWatch や useFormState フックはそれらを使用するコン ポーネントレベルで再レンダリングを分離することを可能にしている #ReactLT
21 Subscription ベースの状態管理 Subscription ベースの状態管理とは? • コンポーネントで値の変更をサブスクライブし、 受け取った値に応じて状態を更新する • Provider
での状態の更新を避けることができ、 サブスクライブしているコンポーネントでのみ再 レンダリングが発生する • 値に応じて細かい再レンダリングの制御が可能 Provider ConsumerB ConsumerA value state 値の変更通知 値の変更をサブスクライブ 受け取った値に応じて状態を更新 #ReactLT
22 Subscription ベースの状態管理 実現方法 • 値の変更を通知する仕組みと値の変更をサブ スクライブ(購読)して何かしら処理する仕組み さえあれば Subscription ベースの状態管理を
実現できる • React Hook Form ではその仕組みとして RxJS の Subject の簡易的な実装をしている • Subject は React Hook Form が提供する control オブジェクトに含まれる subject.subscribe(value => { setState(value) }) subject.next(value) value={{ subject }} Provider ConsumerB ConsumerA value subject subject state 値の変更通知 値の変更をサブスクライブ 受け取った値に応じて状態を更新 #ReactLT
23 Subscription ベースの状態管理 実装例 • Subscription ベースで状態を管理する useCountState フックの 実装例
◦ 修正前 ▪ https://codesandbox.io/s/subscription-based-usecountstate-before-9spnk ◦ 修正後 ▪ https://codesandbox.io/s/subscription-based-usecountstate-after-b4eef • React Hook Form の watch と useWatch の簡易的な実装例 ◦ https://codesandbox.io/s/react-hook-form-watch-usewatch-implementation-u1r si #ReactLT
24 コンポーネントで使用されている状態のみを更新 #ReactLT
25 コンポーネントで使用されている状態のみを更新 React Hook Form の formState について • React
Hook Form が提供する formState というオブジェクトは isDirty 、 isSubmitting、errors などのフォームに関する状態が含まれている • React Hook Form は formState の内、コンポーネントで使用されている状 態のみを更新して再レンダリングを発生させている #ReactLT
26 こちらは2文字以上入力するとバリデーションエラーが発生するフィールドの例です。 コンポーネントで使用されている状態のみを更新 コンポーネントで使用されている状態のみを更新するとは? #ReactLT
27 コンポーネントで使用されている状態のみを更新 コンポーネントで使用されている状態のみを更新するとは? formState の内 isDirty と errors を使用してログを出力してみます。 フィールドで2文字入力すると以下のような3行のログが出力されます。
合計3回レンダリングされています。 #ReactLT
28 コンポーネントで使用されている状態のみを更新 コンポーネントで使用されている状態のみを更新するとは? 続いて、formState の内 errors のみを使用するように修正してログを出力してみます。 同じように2文字入力すると、以下のような2行のログが出力されます。 合計3回のレンダリングから2回のレンダリングに減りました。 #ReactLT
29 コンポーネントで使用されている状態のみを更新 コンポーネントで使用されている状態のみを更新するとは? これは、コンポーネントで使用している errors のみ更新され、isDirty などの errors 以外の状 態は更新されないためです。
これにより不要な再レンダリングが排除されます。 #ReactLT
30 コンポーネントで使用されている状態のみを更新 実現方法 • Proxy や Object.defineProperty/Object.defineProperties を活用してコン ポーネントで使用されている状態のみを更新し、不要な再レンダリングを排 除することができる
• React Hook Form では Object.defineProperty の getter で状態が使用さ れているかを検知し、使用されている状態のみを更新するようにしている #ReactLT
31 コンポーネントで使用されている状態のみを更新 実装例 • コンポーネントで使用されている状態のみを更新する useAsyncフックの実 装例 ◦ 修正前 ▪
https://codesandbox.io/s/dependency-collection-useasync-before-5epsq ◦ 修正後 ▪ https://codesandbox.io/s/dependency-collection-useasync-after-30o24 #ReactLT
32 まとめ • React Hook Form においてパフォーマンスは重要であり、不要な再レンダ リングを排除することは主要な目標の一つ • React
は useCallback・useMemo・React.memo・Context の使用 ・Context の分割によりパフォーマンスを最適化することができる • React Hook Form はSubscription ベースの状態管理を採用し、コンポー ネントで使用されている状態のみを更新することにより再レンダリングを最 適化している #ReactLT
33 パフォーマンスのボトルネックが見つかった場合など、 本日紹介した再レンダリングの最適化を実践してみてください 🙌 #ReactLT
34 時間の都合上、実装例の解説は出来なかったため、 次回イベント or テックブログに乞うご期待…!👋 #ReactLT