Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
Reconciliationの世界
Search
Sponsored
·
Ship Features Fearlessly
Turn features on and off without deploys. Used by thousands of Ruby developers.
→
did0es
November 01, 2024
Technology
31
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
【前編】このAPIいつ使うん?あの機能なに?V8のドキュメント、全部読んでみた
shuta13
0
150
TypeScript Compiler APIとPHP-Parserを活用し、TypeScriptとPHPで型を共有する
shuta13
1
960
ブラウザの投機的読み込みと投機ルールAPIを理解し、Webサービスのパフォーマンスを最適化する
shuta13
3
390
うわっ...私のSwagger、古すぎ...?grpc-gateway向けのSwaggerと向き合う
shuta13
0
210
ViteとTypeScriptのProject Referencesで 大規模モノレポのUIカタログのリリースサイクルを高速化する
shuta13
3
400
歴代のWeb Speed Hackathonの出題から考えるデグレしないパフォーマンス改善
shuta13
8
920
なぜクラウドサービスで Web コンソールを提供するのか
shuta13
4
2.5k
5分でわかるPreactのVDOMで作るWebエディタ
shuta13
0
290
TailwindCSSでUIライブラリを作る際のハマりどころ
shuta13
0
830
Other Decks in Technology
See All in Technology
AgentCore Runtime上にAgentic Coding基盤を構築・展開する際の設計ポイントと限界点 / Design considerations and limitations when building an agentic coding platform on AgentCore Runtime
har1101
5
630
技術的負債から考える、AI時代のエンジニアリング投資 — ビズリーチの技術的負債と向き合った経験から、変更し続けられるソフトウェアを考える/ technical-debt-con2026
visional_engineering_and_design
4
3.5k
AIで社員の自主発信に広報目線を組み込む
_mossann_t
0
140
Minecraft JavaのMODをSwiftで作る
1mash0
0
190
株式会社シーエーシー エンジニア向け会社紹介資料
cac
0
57k
ADKで始める業務改善 - AIエージェント開発時の考えと設計
harappa80
2
260
The Knowledge Spine: A Machine-Executable Ontology for Governed Marketing Activation
vananth22
0
120
作って終わりじゃないサーバーレス 〜9年運用する大規模EC物流API基盤の設計・運用のリアル〜
zozotech
PRO
0
430
EventBridge に「合流」はない ― サーバーレスのワークフローを育てるということ / No Join in EventBridge
yusukeshimizu
2
430
AIエージェントの一手は 誰も見ていない - Falco拡張OSS「Prempti」とeBPFで サーバーレス実行基盤を二層防御する
keitah
0
460
事業課題から技術的負債に向き合う
sansantech
PRO
2
2.2k
ソフトウェアDNAとクラウドエージェントのススメ
cloudace
0
120
Featured
See All Featured
Leveraging Curiosity to Care for An Aging Population
cassininazir
1
500
Mobile First: as difficult as doing things right
swwweet
225
10k
Building Better People: How to give real-time feedback that sticks.
wjessup
370
20k
Site-Speed That Sticks
csswizardry
13
1.5k
DBのスキルで生き残る技術 - AI時代におけるテーブル設計の勘所
soudai
PRO
68
57k
The Hidden Cost of Media on the Web [PixelPalooza 2025]
tammyeverts
2
500
Leo the Paperboy
mayatellez
10
2.3k
Future Trends and Review - Lecture 12 - Web Technologies (1019888BNR)
signer
PRO
0
3.8k
How STYLIGHT went responsive
nonsquared
100
6.3k
Responsive Adventures: Dirty Tricks From The Dark Corners of Front-End
smashingmag
254
22k
Design and Strategy: How to Deal with People Who Don’t "Get" Design
morganepeng
133
19k
Collaborative Software Design: How to facilitate domain modelling decisions
baasie
1
320
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