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
Reconciliationの世界
Search
Sponsored
·
SiteGround - Reliable hosting with speed, security, and support you can count on.
→
did0es
November 01, 2024
Technology
0
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Reconciliationの世界
ReactのReconciliationについて深ぼる話です
did0es
November 01, 2024
More Decks by did0es
See All by did0es
TypeScript Compiler APIとPHP-Parserを活用し、TypeScriptとPHPで型を共有する
shuta13
1
370
ブラウザの投機的読み込みと投機ルールAPIを理解し、Webサービスのパフォーマンスを最適化する
shuta13
3
330
うわっ...私のSwagger、古すぎ...?grpc-gateway向けのSwaggerと向き合う
shuta13
0
150
ViteとTypeScriptのProject Referencesで 大規模モノレポのUIカタログのリリースサイクルを高速化する
shuta13
3
360
歴代のWeb Speed Hackathonの出題から考えるデグレしないパフォーマンス改善
shuta13
8
860
なぜクラウドサービスで Web コンソールを提供するのか
shuta13
4
2.5k
5分でわかるPreactのVDOMで作るWebエディタ
shuta13
0
270
TailwindCSSでUIライブラリを作る際のハマりどころ
shuta13
0
810
codemodとうまく付き合うには
shuta13
0
3k
Other Decks in Technology
See All in Technology
Amazon Bedrock AgentCore ワークショップ JAWS UG TOHOKU / amazon-bedrock-agentcore-workshop-jawsug-tohoku-2026
gawa
9
510
AI活用を推進するために ファインディが下した、一つの小さな決断
starfish719
0
280
AIの性能が向上しても未解決な組織の重大問題は何か?/An Unsolved Organizational Problem in the Age of AI
moriyuya
3
500
チームで進めるAI駆動アジャイル×ウォーターフォール
kumaiu
0
120
AI-DLCを活用した高品質・安全なAI駆動開発実践 / AI Driven Development with AI-DLC
yoshidashingo
0
160
エンジニアリング戦略の作り方 / Crafting Engineering Strategy
iwashi86
15
5k
Agentic ERPをどう設計するか ー 受発注エージェントを動かす、現場の知見と設計思想ー
recerqainc
1
2k
Chart.js が簡単に使えるようになっていたので OGP 画像生成に使った話
kamekyame
0
170
あなたの AI ワークスペースに、 専門コーダーを連れてくる - Amazon Quick Desktop 最新情報
kawaji_scratch
1
120
サプライチェーンセキュリティの空白地帯 - 信頼できる”依存性”の未来を考える
rung
PRO
2
800
実装は速くなった、レビューはどうする? ― 自身のレビューをAIで再現させるサーヴァントエンジニアリングのすゝめ / Implementation got faster. So what about reviews? — An invitation to Servant Engineering: Recreating your own code reviews with AI
nrslib
7
4.3k
AWSシリコン最前線 〜AI時代のチップ選択を読み解く〜
htokoyo
2
290
Featured
See All Featured
Measuring & Analyzing Core Web Vitals
bluesmoon
9
860
Avoiding the “Bad Training, Faster” Trap in the Age of AI
tmiket
0
170
Conquering PDFs: document understanding beyond plain text
inesmontani
PRO
4
2.8k
Refactoring Trust on Your Teams (GOTO; Chicago 2020)
rmw
35
3.5k
Highjacked: Video Game Concept Design
rkendrick25
PRO
1
380
Fireside Chat
paigeccino
42
3.9k
HTML-Aware ERB: The Path to Reactive Rendering @ RubyCon 2026, Rimini, Italy
marcoroth
1
160
Leadership Guide Workshop - DevTernity 2021
reverentgeek
1
300
How to Build an AI Search Optimization Roadmap - Criteria and Steps to Take #SEOIRL
aleyda
1
2.1k
JavaScript: Past, Present, and Future - NDC Porto 2020
reverentgeek
52
6k
Deep Space Network (abreviated)
tonyrice
0
170
ReactJS: Keep Simple. Everything can be a component!
pedronauck
666
130k
Transcript
Reconciliationの世界 CAM, Inc. Creative Division 平井 柊太
自己紹介 平井 柊太(#times_hirai_shuta) 22卒・フロントエンドエンジニア 得意:夜型の生活 苦手:朝全般・花粉 学生の頃は機械学習の研究をして 遊んでました OSS 関連を細々とやってます
GitHub: shuta13 2
本日お話すること 1. Reconciliationとは 2. React Reconciler 3. Reactを再現する 4. 余談
5. 応用 6. まとめ 3
❏ ReactとReconciliationの 仕組みを知る ❏ 仮想DOMの正体を知る ❏ TypeScriptの型システムの 健全性を知る 4 ねらい
Reconciliationとは 5
本資料におけるReconciliation ⇒ 差分検出処理 ❏ “前(old)”と“後(new)”の2つの差分を取る(diff)処理のこと ⇒ 木構造の比較 ❏ DOMに対応する何かしらの木構造体 ❏
計算量(オーダー : O)はどう抑え込む? ❏ 愚直にやるとn個のノードに対してO(n^3) ❏ 頭の体操:1000個のノードだと計算量は?→ 6
React Reconciler 7
ReactのReconciliation 以下2つによりO(n)まで計算量を抑え込む ❏ 異なる型(type)の2つの要素は異なるツリーを生成する ❏ e.g. div と span は異なるツリーを生成する
❏ 特定のプロパティ( props )を与え、子要素が変更される可能性を検知する ❏ 特定のプロパティ ⇒ key ❏ 配列の並び替えを効率よく行うためにこのような識別子が必要 ❏ 無駄な reconciliation を抑制できて Happy 8
ReactのReconciliationにおけるデータ構造 reconciliationとは雑に表現すると「木構造の比較を再帰的に行う処理」 Stack(React <= 16) ❏ 差分検出を中断不可能かつ同期的に処理する Fiber(React > 16)
❏ 差分検出を小分けにする ❏ 小分けにしたものに優先順位をつけ、非同期的に処理する 9
React を再現する 10
※ 具体的な実装を載せると長いので どういったものを実装するかを話します 11
Reactが動く流れ ❏ React要素を生成 ❏ State更新のタイミングでreconciliation ❏ タイミング : setState が
call された瞬間 ❏ 前と後の要素ツリーを比較し、更新・削除 ❏ 親から子に対して繰り返す ❏ 更新済みの要素ツリーをDOMもしくは他のツリーに反映 ❏ React 要素を元の形に整形して Root Container に Attach ❏ DOM 以外もある ⇒ React Native, React Three Fiber 12
JSX(React JavaScript Markup) ❏ Reactの特徴の1つである宣言的UIの実現 ❏ JSXはそのままでは動かない ❏ あくまで React.createElement
の Syntax Suger ❏ Babel, TSC などで JS に変換する ❏ Transpiler, Compiler によるが大抵変換先を変更できる(応用) 13
ほしいものリスト ❏ DOM に対応した木構造( React 要素 )にするもの ❏ React 要素を差分検出するもの
❏ React 要素をレンダリングするもの 14
ほしいものリスト ❏ DOM に対応した木構造(React 要素)にするもの ⇒ React(createElement) ❏ React 要素を差分検出するもの
⇒ react-reconciler ❏ React 要素をレンダリングするもの ⇒ ReactDOM(render) 15
React(createElement) ❏ JSXをTranspileすると得られる createElement 関数の実装 ❏ createElement(type, props, children) ❏
type [string | Function]: HTMLElement の名前もしくは Functional Component ❏ props [object]: key や ref などの Props ❏ children [Array<Element>]: 子要素の配列 ❏ この関数は DOM と1対1対応のオブジェクトを返す ❏ いわゆる仮想DOM ❏ ただの JS オブジェクト 16
react-reconciler ❏ fiberという単位で小分けにして時間をずらしながら実行 ❏ fiber は小分けにし、次に作業を行う要素を簡単に見つけるためのデータ構造 ❏ fiber は child,
parent, sibling へのリンクを持っている ❏ child, siblingが無い場合、parentのsiblingに移動していく ❏ parentにsiblingが無い場合はrootに向かってさかのぼっていく 17
ReactDOM(render) ❏ React 要素から生成した DOM を root の DOM(container) に反映する
❏ ReactDOM.render(<App />, document.getElementById(“root”)) ❏ propsからarrtibuteやeventの登録 ❏ HTMLElementの挿入 ❏ 差分検出処理もここで呼び出す 18
ここまでで一旦Reactの話終了 詳しく : https://github.com/shuta13/react-deep-dive/ 19
余談 - @types/react 20
@types/reactの興味深い点 ❏ bivarianceHack という TypeScript の型システムを悪用した実装がある ❏ 何が嬉しい : メソッドの性質を利用して関数に双変性を持たせられる
❏ bivariance = 双変 ❏ 双方に代入可能であるかつ、サブセットも同様の性質をもつということ ❏ A ⇔ B ならば P<A> ⇔ P<B> ❏ この項における決まり ❏ Aは広い型、Bは狭い型とする(e.g. type A = number; type B = 1; ) ❏ 矢印を右のように定義する : ⇔は双変、⇒は共変(covariance)、⇐は反変(invariance) ❏ 「矢印の先は矢印の元に代入が可能」と読む 21
TypeScriptの型システムにおける矛盾 ❏ TSでは配列を共変(A ⇒ B)として扱っている ❏ number ⇒ 1 ならば
Array<number> ⇒ Array<1> ❏ 通常、メソッドの引数は反変(A ⇐ B)なのでメソッドは反変 ❏ number ⇒ 1 ならば (arg: number): void ⇐ (arg: 1): void ❏ Array<number>.push() ⇐ Array<1>.push() は成り立つ? → いいえ ❏ メソッドは反変のはずだが、Arrayが共変であるため代入不可能 ❏ TSではこの代入が可能 ❏ つまりメソッドを双変として扱っている 22
TypeScriptにおけるメソッドと関数の扱い ❏ TSではメソッドと関数を区別している ❏ メソッドは双変、関数は反変 ❏ type Func = {
foo: (a: A) => void } と type Method = { foo(a: A): void } は別物 ❏ しかし Method から foo を取り出す( Method[“foo”] )と関数扱いになる ❏ 型としては関数だが、メソッドとしての性質は残る ❏ つまり双変な関数が作れる!(bivarianceHack の正体) ❏ Playground で検証してみました 23
応用例 - Preact 24
Preactとは ❏ https://github.com/preactjs/preact ❏ Reactの軽量版としての再実装ライブラリ ❏ ReactからAPIを厳選している ❏ reconciliationの処理をフルスクラッチで書き直している ❏
一部の JSX の Transpiler 以外全て内製 ❏ React v17移行の jsx-runtime は Preact も同様に内製している ❏ babelのplugin/tscを用いることもReact同様に可能 ❏ JSX Pragma/JSX Factoryを h に書き換える 25
応用例 - React Three Fiber 26
React Three Fiberとは ❏ https://github.com/pmndrs/react-three-fiber ❏ React 向けの Three.js Renderer
❏ React JSX を Three.js の記法に変換している ❏ 変換の際に reconciliation も行っている ❏ react-reconciler の wrapper ❏ 内部で react-reconciler を呼び出している ❏ DOM ではなく Three.js の記法に1対1対応したJS オブジェクトを用いて fiber ツリーを作成 ❏ コードの解説 : https://codyb.co/articles/a-technical-breakdown-of-react-three-fiber 27
応用例 - Custom JSX Renderer 28
Custom JSX Renderer ❏ Render を自作するには前述の通り以下の方法で実現可能 ❏ JSX Pragma/JSX Factoryを設定し、独自の
createElement 関数を使う ❏ react-reconciler に独自の createElement 関数で生成した VDOM を渡す ❏ コアチームで開発中の OSS における取り組み ❏ Preact の手法に倣って Render を実装している ❏ コードベース(誰でも見られます) ❏ 実装の意図 : Editor.js の Plugin を JSX で記述出来るようにする ❏ 元は直接 DOM 操作を行うような JS の Class ❏ React Three Fiber の思想に倣って仮想 DOM と Class を1対1対応させている ❏ Reconciler は只今絶賛実装中です...(#times_hirai_shuta で経過が眺められます) 29
まとめ ❏ React の肝は react-reconciler ❏ 差分検出の仕組みが全てここに集約されている ❏ これを wrap
した OSS や、書き直した OSS が存在する ❏ 仮想 DOM などの一見とっつき難い言葉も仕組みを通せば理解出来る ❏ 一言で表現しにくいものに適当な名前をつけたに過ぎない場合がある ❏ とにかく仰々しい単語と思って必要以上にビビらなくて大丈夫です ❏ TypeScript の型システムは不健全 ❏ @types/react で悪用もとい活用されている ❏ 健全性について需要があればもう少し掘り下げて話します 30
ご清聴ありがとうございました 31