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
フロントエンドUIフレームワークのこれまでとこれから
Search
TOMIKAWA Sotaro
September 11, 2026
Programming
3.1k
5
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
フロントエンドUIフレームワークのこれまでとこれから
https://frontend-conf.fukuoka.jp/2026/speakers/tomikawa-sotaro?hl=ja
TOMIKAWA Sotaro
September 11, 2026
More Decks by TOMIKAWA Sotaro
See All by TOMIKAWA Sotaro
ReactとSvelteのその先、Ripple-TS / Beyond React and Svelte: Ripple-TS
ssssota
3
2.7k
Atomics APIを知る / Understanding Atomics API
ssssota
2
1.5k
なんでRustの環境構築してないのにRust製のツールが動くの? / Why Do Rust-Based Tools Run Without a Rust Environment?
ssssota
15
56k
Web技術を最大限活用してRAW画像を現像する / Developing RAW Images on the Web
ssssota
2
3.4k
漸進。
ssssota
0
3.7k
Preact、HooksとSignalsの両立 / Preact: Harmonizing Hooks and Signals
ssssota
1
3.9k
useSyncExternalStoreを使いまくる
ssssota
6
7.1k
React CompilerとFine Grained Reactivityと宣言的UIのこれから / The next chapter of declarative UI
ssssota
8
6.3k
新しいAPI createRawSnippet触ってみた / What is the createRawSnippet?
ssssota
2
350
Other Decks in Programming
See All in Programming
Intent as Code
shoppingjaws
6
1.1k
Everything will be SERVERLESS — 信じて運用した10年の経験値 / Everything Will be Serverless — Lessons Learned from 10 Years of Operational Experience
seike460
PRO
1
610
すこし踏み込む CancellationToken
htkym
2
1.5k
ゲームコントローラやキーボードのファームウェアをSwiftで書く
kishikawakatsumi
1
270
Streamlitで実現する自然言語データアプリ開発
ayumu_yamaguchi
1
330
JPUG勉強会 OSSデータベースの内部構造を理解しよう(第2回)
oga5
0
280
Vue Fes Japan 2026 タイムテーブル徹底解説
448jp
1
570
マイコン向けの軽量Ruby「PicoRuby」で各種デバイスを制御するネイティブアプリの実現手法
bash0c7
0
460
Starting & Sustaining Code-Based E2E Testing for Non-Coding QA Teams( #jasstniigata )
teyamagu
PRO
1
780
コードレビューのボトルネックを"する側"と"される側"の両面から解消する
yub0n
1
680
半永久的に提供し続けられるプライベートクラウドを目指して ― 利用者の認知負荷を抑えるAPI抽象化とハードウェア世代交代の基盤設計
tomokon
0
320
AgentCore CLI で進化した AWS での AI エージェントの作り方 : 必要な機能を必要な時に
icoxfog417
PRO
4
400
Featured
See All Featured
Bootstrapping a Software Product
garrettdimon
PRO
306
120k
Primal Persuasion: How to Engage the Brain for Learning That Lasts
tmiket
0
490
WCS-LA-2024
lcolladotor
0
840
Claude Code どこまでも/ Claude Code Everywhere
nwiizo
68
58k
Refactoring Trust on Your Teams (GOTO; Chicago 2020)
rmw
35
3.8k
Product Roadmaps are Hard
iamctodd
55
13k
職位にかかわらず全員がリーダーシップを発揮するチーム作り / Building a team where everyone can demonstrate leadership regardless of position
madoxten
69
66k
Agile Leadership in an Agile Organization
kimpetersen
PRO
0
250
A better future with KSS
kneath
240
18k
Bridging the Design Gap: How Collaborative Modelling removes blockers to flow between stakeholders and teams @FastFlow conf
baasie
0
710
The Spectacular Lies of Maps
axbom
PRO
1
1.1k
Exploring anti-patterns in Rails
aemeredith
4
520
Transcript
フロントエンドUIフレームワークの これまでとこれから ssssota #fec_fukuoka
Hi there 👋 TOMIKAWA Sotaro / ssssota 仕事はReact、趣味はSvelte/Preact フロントエンドフレームワークぜんぶすき ⼤学の2年間だけ福岡に住んでいました
フロントエンドUIフレームワーク
React Svelte フロントエンドUIフレームワーク SolidJS Preact Vue.js Angular
フロントエンドUIフレームワーク → 今回はWebを第⼀のプラットフォームとする宣⾔的UIを記述するための ライブラリ・フレームワークを指す
の、これまでとこれから
歴史を順に追っていく
HTML(1990年代前半〜) HTMLは、広義の宣⾔的UIである。 ⽂書構造をマークアップするもの。
動的なWeb(1995年ごろ〜) JavaScriptの登場、HTMLを操作できるように。 Java Applet, Flash, Silverlightでリッチな表現も登場。
Ajax(2005年ごろ〜) Asynchronous JavaScript and XML. ⾮同期で情報を取得して、画⾯を更新するように。
jQuery(2006年ごろ〜) jQueryでDOM操作やAjaxが容易に... 操作と更新が増え続け... コードは複雑に...
命令的UI
// 命令的UI let count = 0; const result = document.getElementById('result');
const doubleResult = document.getElementById('double-result'); const button = document.getElementById('increment'); button.addEventListener('click', () => { count++; result.textContent = count; doubleResult.textContent = count * 2; });
Model - View の分離 Backbone.js(2010年ごろ〜)など、 Model - Viewを分離するアプローチもあったが 描画は開発者が管理する必要があり苦しい。
宣⾔的UI
Knockout
Knockout(2012年ごろ〜) テンプレートとObservablesを使ったライブラリ。 `data-bind` 属性をHTMLに⼊れて表現する。
<div> <p data-bind="text: count"></p> <button data-bind="click: increment">+1</button> </div> <script> const
count = ko.observable(0); function increment() { count(count() + 1); } ko.applyBindings({ count, increment }); </script>
現代に⾄る宣⾔的UIの祖? HTMLとは異なり、 JavaScriptから値を取得し、表⽰ 値の変化に応じて、使⽤箇所を更新する
AngularJS, React, Vue.js, ...
React → 仮想DOM
仮想DOM React(2013年ごろ〜) 状態が変化したら、仮想のDOMツリーを構築、 現在の状態と⽐較することで変化した箇所を特定、更新
仮想のDOMツリー
再レンダー(この時点で画⾯は変わらない)
⽐較(reconciler)
実DOM適⽤(commit)
オブジェクト指向とコンポーネント
class でコンポーネントを定義する コンポーネントの状態、振る舞い、表⽰をまとめて定義する 形式が主流に。 状態はプロパティ、振る舞いはメソッドなど クラスインスタンスをUIコンポーネントとするのは ⼀定理にかなっていた。
class Counter extends React.Component { constructor(props) { super(props); this.state =
{ count: 0 }; } increment() { this.setState(state => ({ count: state.count + 1 })); } render() { return <div> <p>{this.state.count}</p> <button onClick={this.increment.bind(this)}>+1</button> </div>; } }
Vue.js Vue.js 0.X、1.0はKnockout的に使⽤箇所を追跡する。 Vue.js 2.Xは仮想DOMを使うように。
<template> <div> <p>{{ count }}</p> <button @click="increment">+1</button> </div> </template> <script>
export default { data() { return { count: 0 }; }, methods: { increment() { this.count++; } } }; </script>
ロジックの分離 クラスやオブジェクトではstateやライフサイクルに紐づくロ ジックの再利⽤が困難だった。
React Hooks
関数コンポーネントへ `useState` を使って状態を表現できるようになり、 ライフサイクルフック等外部接続は `useEffect` になった。 Hook単体でロジックを持ち、テスト可能、共有可能に。
function useCounter() { const [count, setCount] = useState(0); const increment
= () => setCount(c => c + 1); return { count, increment }; } function Counter() { const { count, increment } = useCounter(); return <div> <p>{count}</p> <button onClick={increment}>+1</button> </div>; }
Vue.js Composition API Reactに追従するようにVue 3 (Composition API)が公開 ロジックとデータを集約して関数を定義できる形式。 旧来のOptions APIに親しんでいたユーザーからの反発は
ありつつも、現在では受け⼊れられている。
<template> <div> <p>{{ count }}</p> <button @click="increment">+1</button> </div> </template> <script>
<script> export default { export default { data() { setup() { return { count: 0 }; const count = ref(0); }, const increment = () => { methods: { count.value++; increment() { }; this.count++; return { count, increment }; } } } }; }; </script> </script>
Signals の普及
SolidJSの登場 Signalsをベースに、JSXで記述できる 細粒度リアクティビティなフレームワーク。 「Reactのような関数コンポーネントで⾼パフォーマンス」 といった⾔説とともに登場。
Signals 値が格納された箱。 使われている箇所(=依存)が追跡できる。 依存を有向グラフで管理。
Fine-grained Reactivity ⽇本語で細粒度リアクティビティ。 Signalsを⽤いることで、利⽤箇所を追跡可能に。 Signalの値が変化した際に、利⽤箇所のみを更新する。
export function Counter() { const [count, setCount] = createSignal(0); const
increment = () => setCount(c => c + 1); return <div> <p>{count()}</p> <button onClick={increment}>+1</button> </div>; }
signalを元に実DOMが作られる
signalが変化する
signalを元に直接書き換える
Svelte 5, Vue Vapor
細粒度リアクティビティへの移⾏ 独⾃のコンパイル時最適化を⾏っていたSvelteは Svelte 5でSignalsベースの細粒度リアクティビティへ。 Vue.jsもVapor modeを開発。
<script> let count = $state(0); function increment() { count =
count + 1; } </script> <div> <p>{count}</p> <button onclick={increment}>+1</button> </div>
似たような話を 🤔
Knockout was right all along. Knockoutは最初から正しかった。 Svelte 5のRunesを紹介する記事の⼀節。 細粒度リアクティビティはSolidJSが原点ではなく、 Knockoutが原点に近い。
Vue Vaporも仮想DOMがなかったVue 1な仕組みに近い。
なぜ現代に帰ってきたのか そもそも仮想DOMが流⾏ったのは、テンプレートではなく JavaScriptとして扱いやすい形で、SSRや他プラットフォー ムへの活⽤などを⾒据えていたため。 そこから細粒度リアクティビティに帰ってきたのは、 JavaScriptのコンパイル技術や最適化が進歩し、 Knockoutの課題感を現代的な基準でクリアできたため。
ここまで歴史
UIフレームワークをいろんな⾯から⾒る
UIフレームワークの記述⽅法
JSX (TSX) いまのフロントエンド開発者で知らぬものはいない。 TypeScriptやそれ以外のツールチェインも標準サポートする 数少ないECMAScript拡張構⽂。 <p>Hello</p> は、 jsx("p", {children: "Hello"})
などと解釈できる。
テンプレート (SFC) HTML⾵DSL。 `<script>` や `<style>` タグを利⽤し、装飾も可能。 変換を前提とするので、JavaScriptで表現しづらいことも テンプレートは表現しやすい。 (双⽅向バインディングなど)
JSX vs. テンプレート JSX→独⾃の記法を覚える必要が少ない。⽐較的ただのJS 各ツールチェインのサポートを受けやすい。 テンプレート→ UI特化の構⽂で簡潔に記述できる。 細粒度リアクティビティと相性がいい。 ツールチェインのサポートは受けづらい。
細粒度リアクティビティ と JSX
関数コンポーネントは⼀度だけ実⾏する 細粒度リアクティビティなフレームワークでは、 ⼀般的に関数コンポーネントは初回しか実⾏されない。 ⼀度の実⾏で、コンポーネントの全貌を伝える。 状態変化毎に実⾏されるReactなどに慣れていると違和感。
SolidJS JSXを記述し細粒度リアクティビティを実現する。 JSXをコンパイルすることで最適化が⾏われる。 コンポーネント内で早期リターンができないなど、 記法への制約が強い。 分岐や反復のために、`<Show>`や`<For>`がある。
export function Counter() { const [count, setCount] = createSignal(0); const
increment = () => setCount(c => c + 1); const reset = () => setCount(0); return <Show when={count() > 0} fallback={<button onClick={increment}>Start</button>} > <p>{count()}</p> <button onClick={increment}>+1</button> <button onClick={reset}>Reset</button> </Show>; }
Preact @preact/signals というパッケージを使ってSignalsが 導⼊できる。これにも`<Show>`や`<For>`がある。 Preact⾃体は軽量な仮想DOMベースのライブラリなので、 早期リターンを使うと、従来の差分検出で更新される。
Vue JSX Vapor Vue.jsには細粒度リアクティビティを⽤いるVapor modeが ある。JSXも、それらを合わせたVue JSX Vaporもある。 例に漏れず早期リターンができない。 `v-if`や`v-for`といったディレクティブがある。
function Counter() { const count = ref(0); const increment =
() => { count.value += 1; }; const reset = () => { count.value = 0; }; } return ( <> <template v-if={count.value > 0}> <p>{count.value}</p> <button v-on={{click: increment}}>+1</button> <button v-on={{click: reset}}>Reset</button> </template> <button v-else v-on={{click: increment}}>Start</button> </> );
テンプレートと細粒度リアクティビティ テンプレートの場合は早期リターンという概念⾃体が 存在しないため、概念上の整合性が取りやすい。 Vue.jsやSvelteは独⾃の記法を覚える必要はあれど、その実 細粒度リアクティビティと相性は悪くない。
<script> let count = $state(0); const increment = () =>
{ count += 1; }; const reset = () => { count = 0; }; </script> {#if count > 0} <p>{count}</p> <button onclick={increment}>+1</button> <button onclick={reset}>Reset</button> {:else} <button onclick={increment}>Start</button> {/if}
テンプレートとTypeScript
TypeScriptのサポートを受けるために TypeScriptはJSXしかサポートしていないので、 Vue.js、Svelteなどは独⾃のサポートが必要。 LSPをラップしたCLI、IDE拡張をそれぞれ提供している。 • vue-tsc • svelte-check
TypeScriptの進化
TypeScript Content mappers tsgo化に際しプラグイン機能が利⽤できなくなった。 それを置き換える形でContent mappers APIが整理中。 Vue.jsやSvelteなどの型サポートがより容易かつ⾼速に。 IPC(プロセス間通信)を⽤いる。
第3のテンプレート
TSRX React, Svelteなどに携わってきたDominic Gannaway⽒ が主導する「JSXの精神的後継」。 JSXのようにフレームワーク中⽴ながら`<style>`を使える、 分岐や反復を明⽰的に。
export function Counter() @{ const [count, setCount] = createSignal(0); const
increment = () => setCount(c => c + 1); const reset = () => setCount(0); @if (count() > 0) { <> <p>{count()}</p> <button onClick={increment}>+1</button> <button onClick={reset}>Reset</button> </> } @else { <button onClick={increment}>Start</button> } }
UIフレームワークのパフォーマンス
実⾏速度 細粒度リアクティビティがわずかに優位。 仮想DOMなアプローチではツリーの構築・差分検出が ⾼コストになりがち。
None
None
Reactの記述で速くできるか
React Compiler Reactのメモ化を⾃動で⾏う。 無駄な計算をスキップできる可能性が⾼まる。 React FirというプロジェクトもReact Confで共有されたが 情報は特に出ていない。
Octane Dominic Gannaway⽒のプロジェクト。 JSX React⾵の記述で⾼いパフォーマンスを 仮想DOMも、Signalsも無しで実現する。 状態の変化で関数コンポーネントは再実⾏される。 JSXはDOM操作のコードに変換される。
バンドルサイズ 細粒度リアクティビティが⼩さい傾向にあるものの、 仮想DOMだからといって⼤きいわけではない。 Preactは⼩さいし、Reactは⼤きい。
None
Reactはデカい
⼩型のReact ⾔わずと知れたPreact、Reactに追従できていないため、 互換とは⾔いづらい。 @tanstack/redact、ReactのAPI互換性を重視しつつ、 Transitionなどを削ることでバンドルサイズ削減を果たす。
Scheduler, Lane, Fiber, ... Reactでは、状態の更新の優先度がLaneで管理され、 タスクはschedulerに委託し、、 Fiberツリーでこれらを持ちまわり、、、 圧倒的なまでの抽象化。何を抽象化しているか?
Suspense / Transition
表と裏 タスクの始まりをユーザーに⾒せつつ、タスクの完了を待つ • useTransitionのisPendingで変更の待機を⾒せる • Suspenseで取得を待つ ユーザーの体験を損ねないための機能 →⾮同期のベースになっている
Async React
⾮同期を前提に Async ReactはReactを⾮同期に考え直すもの。 ライブラリやフレームワークも含めた⽅向性を⽰すもの。 現状のReact公式ドキュメントLearnには TransitionやSuspenseについての⾔及がない。 ドキュメントの更新もAsync Reactのスコープ。
Async **
Asynchronous Svelte Svelteの⾮同期処理をより強⼒にする提案。6で安定化予定 コンポーネントトップレベルでawaitを可能に。 ReactはユーザーがTransitionを強く意識する必要があった ⼀⽅、Svelteは⾮同期を⾃動Transitionするような仕組みに
Async Solid (Solid 2.0) v1に存在した⾮同期向けAPIは削除、 AsyncをSignalsのプリミティブとして扱う。 awaitをコンポーネント内で書かずとも、 同期処理と同様に(透過的に)⾮同期が扱える。 こちらも⾮同期を強く意識させない構造に。
function Profile(props) { const user = createMemo(() => fetchUser(props.id)); }
return ( <Loading fallback={<Skeleton />}> <h1 class={{ stale: isPending(user) }}> {user().name} </h1> </Loading> );
Async Vue ? `<Suspense>`が実験的に存在しtop-level awaitなどが可能 lazy loadもSuspenseを活⽤。 reactivity coreへの⾮同期統合はされていない。 提案⾃体は存在する。
⾮同期は誰が為に
⾮同期を扱うコンポーネント ⾮同期の仕組みがフレームワークに統合された形で 設計されたものはほぼ存在しなかった。 「データフェッチをコンポーネントで」+「SSR」 この2つを統合していく上で必要性が明らかになってきた。 所謂コロケーション。
データフェッチを扱うために • UIフレームワークからのアプローチ ◦ ◦ React - React Server Components
/ Server Functions Solid 2.0 - Server Functions ◦ ◦ ◦ TanStack Start - Server Functions Nuxt - Server Components SvelteKit - Remote Functions ◦ GraphQL Fragment Colocation • メタフレームワークからのアプローチ • フレームワーク外からのアプローチ
React Server Components Reactがライブラリの域を超えた。 Server Componentsはクライアントで実⾏されない。 データフェッチ以外もまとめて解決する。
Solid 2.0 Server Functions 所謂RPC。 TanStack Startなど、メタフレームワーク側で提供されるよ うな機能をUIフレームワークの⼀部として提供。 SolidStartというメタフレームワークは姿を消し統合。
⾮同期システムの統合
→RPCの統合
→メタフレームワークの統合
UIフレームワークの現実
Reactの圧倒的な使⽤率 2025.stateofjs.com (Usage) tanstack.com/stats (npm downloads)
Reactの圧倒的な使⽤率 2025.stateofjs.com (Usage) tanstack.com/stats (npm downloads)
Reactの圧倒的な使⽤率 2025.stateofjs.com (Usage) tanstack.com/stats (npm downloads)
Reactの圧倒的な周辺ライブラリ Vue.jsやSvelteもライブラリは健闘している。 TanStack等 複数フレームワークに対応するものも増えた。 リッチテキストエディタ、アクセシビリティ、表、D&Dなど ニッチな領域でも有⼒な選択肢がいくつかあるのがReact。
React Foundation Meta、Vercelなど複数の企業が組んでReactを⽀える体制 が整っている。 ReactはMetaだけのものではなくなった。
まとめ
これからのUIフレームワーク 「宣⾔」の範囲、「フレームワーク」の範囲、が拡⼤する。 ReactのTransitionは並⾏性の宣⾔と⾒ることができるし、 Signalsは状態の宣⾔。 UIフレームワークとメタフレームワークの距離が近くなり、 より密接になっていく。
React その確かな技術⼒、利⽤者・ライブラリの多さ、React Foundationなど盤⽯のUIフレームワーク。 Suspense/Transitionは開発者が明⽰的に取り⼊れていく 必要があり、取り⼊れられなければ恩恵が享受できない。 次々と⾰新的な技術を投⼊するReactについていけるか。
React以外 細粒度リアクティビティがトレンド。 内部に細かい差はあれど、構⽂の違いだけが⽬⽴つ状態。 SolidJSやSvelteが並⾏性や⾮同期を扱う仕組みを取り⼊れ リードしている。 パフォーマンスを追求するケースではこちらに分があるか。
おわり UIフレームワークという領域は今もなお進化を続けて、 フロントエンドという障害だらけの道を切り拓いている。 答えはないので、進化を追うのみ。 (正直枯れて欲しい気持ちも)Oo。