Web開発
Reactのメモの扱いが嫌で、VDOMライブラリを6日間で構築しました
I spent 6 days building my VDOM library as I hated how React handles memo (vflash.github.io)
要約
Reactのmemo()の挙動に不満を感じた著者が、わずか6日間で独自の仮想DOMライブラリ「Tyaff」を構築しました。Tyaffは、純粋なJavaScript(ES6+)で書かれた軽量なVDOMライブラリであり、Reactとは異なるミニマリズムの哲学に基づいています。主な特徴として、memo()が現在のコンポーネントのみをブロックする点、プロップスドリリングなしでmutableなデータを扱える点、Provider/ConsumerなしでPullベースのコンテキストを提供する点などが挙げられます。
全文翻訳
Tyaff
Tyaff — JavaScript用のVDOMライブラリ
独自の仮想DOMとミニマリズムの哲学を持つ、純粋なJavaScript (ES6+) で書かれたReactの軽量な代替。
Reactとの主な違い
memo()は現在のコンポーネントのみをブロックする — 子コンポーネントは独立して自身の更新チェーンを継続し、最適化を予測可能にする
任意のソースからのミュータブルなデータ — コンポーネントは、プロップスドリリングなしで、グローバルストア、シングルトン、またはウィンドウを直接読み取ることができる
Provider/ConsumerなしのPullベースのコンテキスト — 任意のコンポーネントは、context: { key() { ... } }を介して自身をプロバイダーとして宣言し、子コンポーネントはthis.context(key)を介して値を要求する
プロップスを第一引数として — init(props), memo(props), render({ title, items })のようなシグネチャにより、定義内でプロップスの分割代入が可能
キーはレンダリング全体でユニーク — これにより、インスタンスと状態を維持したまま、コンポーネントを異なる親の間で移動できる
主な機能
コンパクトで高性能 — 最小限のAPIサーフェス、カスタムの差分/パッチアルゴリズム、マイクロタスクによるバッチ更新
大量操作に最適化 — Reactよりも高速な逆順、スワップ、親変更
動的なコンテキストツリー — HTMLタグを介した自動伝播を備えた階層型プロバイダーシステム
ファクトリーベースのコンポーネント — 統一された作成パターン、自動メソッドバインディング、柔軟なライフサイクル
遅延マウントを備えたポータル — 任意のDOMコンテナへのアンカーノードによるマウント
キーシステム — ユーザー定義キーはレンダリング全体でユニーク、自動パスベースキー
キー付きフラグメント — ラッパーなしでグループを移動できるグループ化子要素
インストール
npm install tyaff
クイックスタート
```javascript
import { h, Component, mount } from 'tyaff';
const Counter = Component({
count: 0,
increment() {
this.update({ count: this.count + 1 });
},
render() {
return h(
'div',
null,
h('p', null, 'Counter: ' + this.count),
h('button', { onClick: this.increment }, '+')
);
}
});
mount(Counter, document.getElementById('app'));
```
例: コンテキストを持つコンポーネント
```javascript
const ThemeProvider = Component({
theme: 'light',
context: {
theme() {
return this.theme;
},
toggleTheme() {
this.theme = this.theme === 'light' ? 'dark' : 'light';
this.update();
}
},
render() {
return h('div', null, this.props.children);
}
});
const ThemedButton = Component({
render() {
const theme = this.context('theme');
return h('button', { className: 'btn-' + theme }, 'Button');
}
});
mount(
h(ThemeProvider, null, h(ThemedButton))
, document.body
);
```
例: グローバルストア
```javascript
// store.js
export const store = {
count: 0
};
// app.js
import { store } from './store.js';
import { h, Component, mount, refresh } from 'tyaff';
const Counter = Component({
render() {
return h('div', null, 'Count: ', store.count);
}
});
mount(Counter, document.getElementById('app'));
// Update
store.count = 55;
await refresh(); // all components will re-read the store
```
リソース
ドキュメント — 完全なAPI説明、使用例、ライフサイクル、コンテキスト、ポータル、最適化
ライブデモ — ブラウザでのインタラクティブなデモ
ベンチマーク — tyaffとReactのパフォーマンス比較 (14シナリオ)
変更履歴 — プロジェクトの新機能
謝辞
このプロジェクトは、人間とAIのコラボレーションのショーケースです:
人間: アーキテクチャ、設計上の決定、コードレビュー、ビジョン
Qwen: 開発、最適化、ドキュメント、ビジュアルデザイン
GLM: 開発、最適化
Gemini: 研究と分析 (検索経由)
ブラウザサポート
Chrome 86+
Firefox 78+
Safari 14+
ES6モジュールをサポートするすべてのモダンブラウザ
ライセンス
MIT
このサイトはオープンソースです。このページを改善してください。