Performance
Tips for keeping Taffy layouts blazing fast.
Taffy is designed to be efficient and high-performance, but specific patterns can affect performance.
1. Pre-Allocate Capacity
If you know the node count, use withCapacity to avoid re-allocations.
2. Incremental Layouts
Only changed nodes are recalculated. Taffy acts lazily and only recomputes the branch affected by the change.
Common Pitfalls
1. Excessive Nesting
Every level of depth adds complexity to the recursive algorithm.
- Bad:
View -> View -> View -> Buttonjust for padding. - Good: Use
paddingon the parent instead of wrapper nodes.
2. Deep Measurement Functions
Custom measure functions (for text/images) are called frequently.
- Optimize: Ensure your measurement callback is fast. Avoid DOM reflows or heavy calculations inside measurements.
Optimization Patterns
Reuse Styles
Creating Style objects in tight loops (e.g., game rendering) can be expensive in JS.
Reuse definition objects where possible.
// ✅ Good const tree = new TaffyTree(); const ITEM_STYLE = new Style({ flexGrow: 1 }); for (let i = 0; i < 1000; i++) { tree.newLeaf(ITEM_STYLE); }
// ❌ Avoid if items are identical const tree = new TaffyTree(); for (let i = 0; i < 1000; i++) { tree.newLeaf(new Style({ flexGrow: 1 })); }
Batch Property Access
Use batch getters and setters to minimize WASM bridge overhead.
Style Batch Update: Instead of setting properties one by one:
const style = new Style(); // ❌ Multiple calls = High overhead style.display = Display.Flex; style.width = 100; style.height = 100;
Use set():
const style = new Style(); // ✅ Single call = Low overhead style.set({ display: Display.Flex, width: 100, height: 100, });
Layout Batch Read: Instead of reading layout properties individually:
const tree = new TaffyTree(); const node = tree.newLeaf(new Style()); tree.computeLayout(node, { width: 100, height: 100 }); // ❌ Multiple calls const layout = tree.getLayout(node); const x = layout.x; const y = layout.y; const w = layout.width; const h = layout.height;
Use get():
const tree = new TaffyTree(); const node = tree.newLeaf(new Style()); tree.computeLayout(node, { width: 100, height: 100 }); // ✅ Single call returns array of values const layout = tree.getLayout(node); const [x, y, w, h] = layout.get("x", "y", "width", "height");
Benchmarking
Use performance.now() to measure your layout pass.
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`);