Concatenation Performance Guide
Overview
tachUI's component concatenation system is designed for optimal performance through intelligent caching, automatic optimization, and efficient DOM manipulation. This guide covers performance characteristics, optimization strategies, and best practices for high-performance applications.
Performance Features
1. Automatic Text Merging
The system automatically merges adjacent text components to reduce DOM complexity:
// Source: Multiple text components
const greeting = Text("Hello, ")
.concat(Text("John"))
.concat(Text("!"))
.concat(Text(" Welcome to tachUI"))
// Optimized result: Single DOM element
// <span>Hello, John! Welcome to tachUI</span>Performance Impact:
- Reduces DOM nodes from 4 to 1 (75% reduction)
- Decreases memory usage
- Improves rendering performance
- Reduces layout thrashing
2. LRU Caching System
Optimization results are cached using an LRU (Least Recently Used) strategy:
import { TextConcatenationOptimizer } from '@tachui/core/concatenation'
// Check cache performance
const stats = TextConcatenationOptimizer.getCacheStats()
console.log(`Cache utilization: ${stats.size}/${stats.maxSize}`)
// Clear cache if needed (e.g., memory pressure)
if (stats.size === stats.maxSize) {
TextConcatenationOptimizer.clearCache()
}Cache Configuration:
- Maximum size: 100 entries
- TTL (Time To Live): 5 minutes
- Eviction strategy: LRU with timestamp validation
3. Smart Optimization Detection
The system analyzes segments before applying optimizations:
const segments = [textSegment1, imageSegment, textSegment2, textSegment3]
// Only optimize when beneficial
if (TextConcatenationOptimizer.shouldOptimize(segments)) {
const optimized = TextConcatenationOptimizer.optimize(segments)
// Result: [textSegment1, imageSegment, mergedTextSegment]
}Performance Monitoring
Development Mode Logging
Enable performance logging in development:
// Set environment variable
process.env.NODE_ENV = 'development'
// Concatenation with performance logging
const result = Text("Hello")
.concat(Text(" World"))
.concat(Text("!"))
// Console output:
// "TachUI Concatenation: Optimized 3 → 1 segments (67% reduction)"
// "TachUI Concatenation: Optimization took 0.52ms for 3 segments"Performance Analysis
Analyze optimization opportunities:
const analysis = TextConcatenationOptimizer.analyzeOptimizationOpportunities(segments)
console.log(`Optimization Analysis:
- Total segments: ${analysis.totalSegments}
- Text segments: ${analysis.textSegments}
- Image segments: ${analysis.imageSegments}
- Interactive segments: ${analysis.interactiveSegments}
- Optimizable pairs: ${analysis.optimizableTextPairs}
- Estimated reduction: ${analysis.estimatedReductionPercent}%`)Custom Performance Metrics
const measureConcatenation = (name: string, concatenationFn: () => any) => {
const start = performance.now()
const result = concatenationFn()
const end = performance.now()
console.log(`${name} concatenation took ${(end - start).toFixed(2)}ms`)
return result
}
// Usage
const userCard = measureConcatenation('User Card', () =>
Image(user.avatar)
.concat(Text(user.name))
.concat(Text(user.title))
.concat(Button("Follow", followUser))
)Optimization Strategies
1. Batch Text Operations
Group text operations to maximize merging benefits:
// ✅ Good: Adjacent text components get merged
const address = Text(user.street)
.concat(Text(", "))
.concat(Text(user.city))
.concat(Text(", "))
.concat(Text(user.state))
.concat(Text(" "))
.concat(Text(user.zipCode))
// Result: Single merged text element
// ❌ Less optimal: Interleaved with other components
const scattered = Text(user.street)
.concat(Image("location-icon.svg"))
.concat(Text(user.city))
.concat(Button("Edit", editAddress))
.concat(Text(user.state))
// Result: No text merging possible2. Minimize Concatenation Chains
Avoid extremely long concatenation chains:
// ❌ Avoid: Very long chains
const longChain = Text("Part 1")
.concat(Text("Part 2"))
.concat(Text("Part 3"))
// ... many more parts
.concat(Text("Part 20"))
// ✅ Better: Group logically or use arrays
const parts = ["Part 1", "Part 2", "Part 3", /* ... */ "Part 20"]
const combined = Text(parts.join(" "))
// Or use VStack/HStack for layout
const groupedContent = VStack(
parts.map(part => Text(part))
)3. Memoize Expensive Concatenations
Use memoization for complex or frequently rendered concatenations:
import { createMemo } from '@tachui/core'
const ExpensiveUserCard = (user: User) => {
// Memoize the concatenation result
const userHeader = createMemo(() =>
Image(user.avatar, { width: 48, height: 48 })
.concat(Text(user.name).modifier.fontSize(18))
.concat(Text(user.title).modifier.fontSize(14))
.concat(Text(`${user.followers} followers`).modifier.fontSize(12))
)
return VStack([
userHeader(), // Cached result
Text(user.bio),
Button("Follow", () => followUser(user))
])
}4. Optimize Modifier Usage
Apply modifiers efficiently in concatenated components:
// ✅ Good: Single modifier application
const styledContent = Text("Important:")
.concat(Text(" Read this message"))
.modifier
.color('#dc3545')
.fontWeight('bold')
.padding(16)
// ❌ Less efficient: Multiple modifier applications
const inefficient = Text("Important:").modifier.color('#dc3545')
.concat(Text(" Read this message").modifier.color('#dc3545'))Memory Management
Cache Management
Monitor and manage cache memory usage:
class ConcatenationManager {
private static memoryThreshold = 50 * 1024 * 1024 // 50MB
static checkMemoryUsage() {
if (performance.memory?.usedJSHeapSize > this.memoryThreshold) {
console.warn('High memory usage detected, clearing concatenation cache')
TextConcatenationOptimizer.clearCache()
}
}
static startMemoryMonitoring() {
setInterval(this.checkMemoryUsage, 30000) // Check every 30 seconds
}
}Component Cleanup
Ensure proper cleanup of concatenated components:
const DynamicConcatenation = () => {
const [items, setItems] = createSignal<string[]>([])
// Use cleanup function for complex concatenations
onCleanup(() => {
// Clear any component-specific caches
TextConcatenationOptimizer.clearCache()
})
const concatenatedItems = createMemo(() => {
let result = null
items().forEach((item, index) => {
const element = Text(item)
if (result === null) {
result = element
} else {
result = result.concat(Text(", ")).concat(element)
}
})
return result
})
return concatenatedItems()
}Benchmarking
Simple Performance Test
const benchmarkConcatenation = () => {
const iterations = 1000
const textParts = Array.from({ length: 10 }, (_, i) => `Part ${i + 1}`)
// Test 1: Individual concatenations
console.time('Individual concatenations')
for (let i = 0; i < iterations; i++) {
let result = Text(textParts[0])
for (let j = 1; j < textParts.length; j++) {
result = result.concat(Text(textParts[j]))
}
}
console.timeEnd('Individual concatenations')
// Test 2: Single text component
console.time('Single text component')
for (let i = 0; i < iterations; i++) {
const result = Text(textParts.join(' '))
}
console.timeEnd('Single text component')
// Test 3: With caching (second run)
console.time('Cached concatenations')
for (let i = 0; i < iterations; i++) {
let result = Text(textParts[0])
for (let j = 1; j < textParts.length; j++) {
result = result.concat(Text(textParts[j]))
}
}
console.timeEnd('Cached concatenations')
}DOM Performance Comparison
const compareDOMPerformance = () => {
const container = document.createElement('div')
document.body.appendChild(container)
// Test 1: Multiple DOM elements
console.time('Multiple DOM elements')
for (let i = 0; i < 1000; i++) {
const span1 = document.createElement('span')
span1.textContent = 'Hello, '
const span2 = document.createElement('span')
span2.textContent = 'World!'
container.appendChild(span1)
container.appendChild(span2)
}
console.timeEnd('Multiple DOM elements')
container.innerHTML = '' // Clear
// Test 2: Single merged element
console.time('Single merged element')
for (let i = 0; i < 1000; i++) {
const span = document.createElement('span')
span.textContent = 'Hello, World!'
container.appendChild(span)
}
console.timeEnd('Single merged element')
document.body.removeChild(container)
}Best Practices Summary
1. Design for Optimization
- Group adjacent text components when possible
- Minimize interleaving of different component types
- Use meaningful semantic groupings
2. Monitor Performance
- Enable development mode logging
- Use browser DevTools to monitor DOM complexity
- Implement custom performance metrics for critical paths
3. Cache Management
- Monitor cache hit rates
- Clear cache during memory pressure
- Use memoization for complex concatenations
4. Memory Efficiency
- Clean up component references
- Avoid creating unnecessary intermediate concatenations
- Use arrays and loops instead of long concatenation chains
5. Production Optimization
// Production-ready concatenation with performance monitoring
const createOptimizedConcatenation = (
components: Array<() => Concatenatable>,
name: string
) => {
return createMemo(() => {
const start = performance.now()
let result = components[0]()
for (let i = 1; i < components.length; i++) {
result = result.concat(components[i]())
}
const duration = performance.now() - start
if (duration > 5) {
console.warn(`Slow concatenation '${name}': ${duration.toFixed(2)}ms`)
}
return result
})
}The concatenation system is designed to provide excellent performance out of the box while giving you the tools to optimize further when needed. By following these guidelines and monitoring performance metrics, you can build highly performant applications with complex component compositions.