パフォーマンス
Taffy レイアウトを高速に保つためのヒント。
Taffy は効率的で高性能に設計されていますが、特定のパターンはパフォーマンスに影響を与える可能性があります。
1. 容量の事前割り当て
ノード数を把握している場合は、withCapacity を使用して再割り当てを減らせます。指定した容量を超えると追加の割り当てが必要になります。
2. 増分レイアウト
Taffy は条件が一致するキャッシュを再利用します。スタイルや構造を変更すると対象ノードと祖先のキャッシュが無効になります。利用可能なスペースなどが変われば、直接変更していない兄弟や子孫も再計算されることがあります。
関連付けた context オブジェクトを直接変更した場合や、測定関数・フォントなど外部の測定条件を変更した場合は、影響するリーフに markDirty(node) を呼んでから computeLayoutWithMeasure() を実行してください。setNodeContext() で値を置き換える場合は自動的にダーティになります。コールバックを渡し直すだけではキャッシュは無効になりません。
一般的な落とし穴
1. 過度なネスト
深さのレベルごとに再帰アルゴリズムの複雑さが増します。
- 悪い:パディングのためだけに
View -> View -> View -> Button。 - 良い:ラッパーノードの代わりに親ノードで
paddingを使用します。
2. 深い測定関数
カスタム測定関数(テキスト/画像用)は頻繁に呼び出されます。
- 最適化:測定コールバックが高速であることを確認してください。測定内での DOM リフローや重い計算を避けてください。
最適化パターン
スタイルの再利用
タイトループで Style オブジェクトを作成する(例:ゲームレンダリング)ことは、JS では高コストになる可能性があります。可能な限り定義オブジェクトを再利用してください。
// ✅ 良い const tree = new TaffyTree(); const ITEM_STYLE = new Style({ flexGrow: 1 }); for (let i = 0; i < 1000; i++) { tree.newLeaf(ITEM_STYLE); }
// ❌ アイテムが同じ場合は避ける const tree = new TaffyTree(); for (let i = 0; i < 1000; i++) { tree.newLeaf(new Style({ flexGrow: 1 })); }
バッチプロパティアクセス
バッチ getter と setter を使用して、WASM ブリッジのオーバーヘッドを最小限に抑えます。
スタイルバッチ更新: プロパティを 1 つずつ設定する代わりに:
const style = new Style(); // ❌ 複数の呼び出し = 高オーバーヘッド style.display = Display.Flex; style.width = 100; style.height = 100;
set() を使用:
const style = new Style(); // ✅ 単一の呼び出し = 低オーバーヘッド style.set({ display: Display.Flex, width: 100, height: 100, });
レイアウトバッチ読み取り: レイアウトプロパティを個別に読み取る代わりに:
const tree = new TaffyTree(); const node = tree.newLeaf(new Style()); tree.computeLayout(node, { width: 100, height: 100 }); // ❌ 複数の呼び出し const layout = tree.getLayout(node); const x = layout.x; const y = layout.y; const w = layout.width; const h = layout.height;
get() を使用:
const tree = new TaffyTree(); const node = tree.newLeaf(new Style()); tree.computeLayout(node, { width: 100, height: 100 }); // ✅ 単一の呼び出しが値の配列を返す const layout = tree.getLayout(node); const [x, y, w, h] = layout.get("x", "y", "width", "height");
ベンチマーク
performance.now() を使用してレイアウトパスを測定します。
const tree = new TaffyTree(); const root = tree.newLeaf(new Style()); const start = performance.now(); tree.computeLayout(root, { width: 1000, height: 1000 }); const end = performance.now(); console.log(`Layout took ${end - start}ms`);