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
·
Ship Features Fearlessly
Turn features on and off without deploys. Used by thousands of Ruby developers.
→
did0es
November 01, 2024
Technology
29
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
55
TypeScript Compiler APIとPHP-Parserを活用し、TypeScriptとPHPで型を共有する
shuta13
1
880
ブラウザの投機的読み込みと投機ルールAPIを理解し、Webサービスのパフォーマンスを最適化する
shuta13
3
380
うわっ...私のSwagger、古すぎ...?grpc-gateway向けのSwaggerと向き合う
shuta13
0
190
ViteとTypeScriptのProject Referencesで 大規模モノレポのUIカタログのリリースサイクルを高速化する
shuta13
3
390
歴代のWeb Speed Hackathonの出題から考えるデグレしないパフォーマンス改善
shuta13
8
900
なぜクラウドサービスで Web コンソールを提供するのか
shuta13
4
2.5k
5分でわかるPreactのVDOMで作るWebエディタ
shuta13
0
280
TailwindCSSでUIライブラリを作る際のハマりどころ
shuta13
0
820
Other Decks in Technology
See All in Technology
AIレビュー時代に必要なのは、SLOで引く撤退ライン
nobuoooo
0
160
DMMブックスのNext.js化を加速させるAI活用 / Migrating DMM Books to Next.js with AI
kentarom
1
270
Does an AI Watermark Survive Translation?
machinetranslation
0
510
Eight Engineering Unit 紹介資料
sansan33
PRO
3
8.3k
The Django UUID Story - DjangoCon US 2026
pauloxnet
0
360
Backstageでつくるセルフサービスな社内開発基盤
kikunosuke75
1
150
hookで自作する Claude Code の「実況ボード」
shinyasaita
2
280
Claude Codeの体系的な理解と知識のフック
oikon48
10
6.4k
名刺メーカーDevグループ 紹介資料
sansan33
PRO
0
1.3k
Bet AI Day 2026丨Agentは、「金融」という巨大産業の何を変えられるのか
layerx
PRO
0
330
Introduction to Sansan, inc / Sansan Global Development Center, Inc.
sansan33
PRO
0
3.2k
LLMアプリ、 雰囲気で運用してませんか? 〜LLMOpsの現在地〜
taka_aki
1
640
Featured
See All Featured
Understanding Cognitive Biases in Performance Measurement
bluesmoon
32
3k
Skip the Path - Find Your Career Trail
mkilby
1
210
JAMstack: Web Apps at Ludicrous Speed - All Things Open 2022
reverentgeek
1
580
Rebuilding a faster, lazier Slack
samanthasiow
85
9.6k
A Tale of Four Properties
chriscoyier
163
24k
Building Adaptive Systems
keathley
44
3.2k
Mozcon NYC 2025: Stop Losing SEO Traffic
samtorres
1
510
The State of eCommerce SEO: How to Win in Today's Products SERPs - #SEOweek
aleyda
2
11k
The MySQL Ecosystem @ GitHub 2015
samlambert
251
13k
The Straight Up "How To Draw Better" Workshop
denniskardys
239
140k
Ruling the World: When Life Gets Gamed
codingconduct
0
310
The Illustrated Guide to Node.js - THAT Conference 2024
reverentgeek
1
460
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