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 Agentの紹介/Introduction to an AI Agent for System Alert Investigation
taddy_919
2
1.6k
Mosaic AI Gatewayでコーディングエージェントを配るための運用Tips / JEDAI 2026 新春 Meetup! AIコーディング特集
genda
0
150
顧客の言葉を、そのまま信じない勇気
yamatai1212
1
320
2026年はチャンキングを極める!
shibuiwilliam
9
1.9k
GSIが複数キー対応したことで、俺達はいったい何が嬉しいのか?
smt7174
3
130
フルカイテン株式会社 エンジニア向け採用資料
fullkaiten
0
10k
Deno・Bunの標準機能やElysiaJSを使ったWebSocketサーバー実装 / ラーメン屋を貸し切ってLT会! IoTLT 2026新年会
you
PRO
0
250
Embedded SREの終わりを設計する 「なんとなく」から計画的な自立支援へ
sansantech
PRO
2
1.9k
AIとともに歩む情報セキュリティ / Information Security with AI
kanny
4
3.2k
All About Sansan – for New Global Engineers
sansan33
PRO
1
1.3k
Introduction to Sansan for Engineers / エンジニア向け会社紹介
sansan33
PRO
6
67k
GitLab Duo Agent Platform × AGENTS.md で実現するSpec-Driven Development / GitLab Duo Agent Platform × AGENTS.md
n11sh1
0
110
Featured
See All Featured
sira's awesome portfolio website redesign presentation
elsirapls
0
140
Impact Scores and Hybrid Strategies: The future of link building
tamaranovitovic
0
200
Money Talks: Using Revenue to Get Sh*t Done
nikkihalliwell
0
150
Un-Boring Meetings
codingconduct
0
200
AI: The stuff that nobody shows you
jnunemaker
PRO
2
240
SEO for Brand Visibility & Recognition
aleyda
0
4.2k
Bridging the Design Gap: How Collaborative Modelling removes blockers to flow between stakeholders and teams @FastFlow conf
baasie
0
440
RailsConf & Balkan Ruby 2019: The Past, Present, and Future of Rails at GitHub
eileencodes
141
34k
Leadership Guide Workshop - DevTernity 2021
reverentgeek
1
200
GraphQLとの向き合い方2022年版
quramy
50
14k
Sam Torres - BigQuery for SEOs
techseoconnect
PRO
0
180
Become a Pro
speakerdeck
PRO
31
5.8k
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