Skip to content

Performance Optimization ​

Directix v2.2.0 introduces extreme performance optimization utilities to reduce bundle size, improve runtime performance, and enhance memory efficiency.

Overview ​

UtilityDescriptionSince
EventDelegationManagerGlobal event delegation to reduce DOM listeners2.2.0
BatchProcessorGeneric batch processor with priority queue2.2.0
DOMBatchUpdaterRead/write separated DOM batch updater2.2.0
VirtualListOptimizerVirtual scrolling with dynamic height caching2.2.0
MemoryLeakDetectorAutomatic memory leak detection and reporting2.2.0
ObjectPoolObject pooling with auto-expand and pre-warming1.11.0+
WeakCacheWeakMap-based cache with LRU eviction1.11.0+

Event Delegation Manager ​

Reduce the number of DOM event listeners by delegating events to a common ancestor.

Basic Usage ​

typescript
import {
  registerDelegatedHandler,
  unregisterDelegatedHandler,
  configureEventDelegation,
} from 'directix'

// Configure (optional)
configureEventDelegation({
  enabled: true,
  root: document, // or a specific container
  events: ['click', 'touchstart'],
  capture: false,
  maxHandlers: 1000,
})

// Register a delegated handler
const id = registerDelegatedHandler('.dropdown-trigger', 'click', (event, target) => {
  console.log('Dropdown trigger clicked:', target)
})

// Unregister when done
unregisterDelegatedHandler(id)

API ​

FunctionDescription
registerDelegatedHandler(selector, event, handler, options?)Register a delegated handler, returns ID
unregisterDelegatedHandler(id)Remove a handler by ID
pauseDelegatedHandler(id)Pause without removing
resumeDelegatedHandler(id)Resume a paused handler
getDelegationStats()Get delegation statistics
startDelegation()Start delegation
stopDelegation()Stop delegation (removes root listeners)

Batch Processor & DOM Batch Updater ​

DOMBatchUpdater ​

Separate DOM reads and writes to avoid forced synchronous layouts (layout thrashing).

typescript
import { domRead, domWrite, getDOMBatchUpdater } from 'directix'

// Schedule a DOM read
domRead(() => {
  const height = element.offsetHeight
  const width = element.offsetWidth

  // Schedule a DOM write based on the read values
  domWrite(() => {
    element.style.transform = `translate(${width}px, ${height}px)`
  })
})

BatchProcessor ​

Generic batch processor with priority queue for grouping operations.

typescript
import { BatchProcessor } from 'directix'

const processor = new BatchProcessor<Task, Result>(
  (tasks) => {
    return tasks.map(task => ({
      id: task.id,
      success: true,
      data: processTask(task.data),
      duration: 0,
    }))
  },
  { maxBatchSize: 50, flushInterval: 16, useRAF: true },
)

// Add tasks
processor.add(myTask, 'default', 100) // data, type, priority

// Force flush
processor.flush()

// Get stats
processor.getStats()

Virtual List Optimizer ​

Optimize virtual scrolling lists with dynamic height caching and VNode recycling.

typescript
import { VirtualListOptimizer } from 'directix'

const optimizer = new VirtualListOptimizer({
  bufferSize: 5,
  estimatedItemHeight: 40,
  dynamicHeight: true,
  recyclePoolSize: 100,
})

// Initialize with total items and container height
optimizer.init(10000, 600)

// Cache known heights
optimizer.cacheItemHeight(0, 48)
optimizer.cacheItemHeight(1, 72)

// Calculate visible range based on scroll position
const range = optimizer.calculateVisibleRange(scrollTop)
// { start: 0, end: 20, total: 10000, startOffset: 0, endOffset: 48000 }

// Handle scroll events
const scrollInfo = optimizer.handleScroll(scrollTop)
// { scrollTop, direction, velocity, isScrolling }

// Recycle and reuse VNodes
optimizer.recycleVNode('item-type', vnode)
const recycled = optimizer.acquireRecycledVNode('item-type')

Memory Leak Detector ​

Automatically detect and report memory leaks in your application.

Basic Usage ​

typescript
import {
  trackResource,
  cleanupResource,
  startLeakDetection,
  getLeakReports,
} from 'directix'

// Start periodic detection
startLeakDetection()

// Track resources that need cleanup
const listenerId = trackResource(
  'event-listener',
  'Window scroll handler',
  () => window.removeEventListener('scroll', handler),
  { target: window },
)

const observerId = trackResource(
  'observer',
  'IntersectionObserver for lazy loading',
  () => observer.disconnect(),
  { tags: ['lazy', 'observer'] },
)

// When component unmounts, clean up
cleanupResource(listenerId)
cleanupResource(observerId)

// Check for leaks
const reports = getLeakReports()
for (const report of reports) {
  console.log(`[${report.severity}] ${report.description}`)
  for (const suggestion of report.suggestions) {
    console.log(`  → ${suggestion}`)
  }
}

API ​

FunctionDescription
configureMemoryLeakDetector(config)Configure detector
trackResource(type, description, cleanup, options?)Track a resource
untrackResource(id)Stop tracking (without cleanup)
cleanupResource(id)Cleanup and untrack
cleanupResourcesByType(type)Cleanup all of a type
takeSnapshot()Take a memory snapshot
getLeakReports()Get detected leak reports
startLeakDetection()Start periodic detection
stopLeakDetection()Stop detection

Enhanced ObjectPool ​

typescript
import { ObjectPool } from 'directix'

const pool = new ObjectPool({
  initialSize: 10,
  maxSize: 100,
  autoExpand: true, // NEW: allow growth beyond maxSize
  createFunction: () => ({ x: 0, y: 0 }),
  resetFunction: (obj) => { obj.x = 0; obj.y = 0 },
})

// Pre-warm the pool (NEW)
pool.preWarm(50)

// Use the pool
const obj = pool.acquire()
obj.x = 10
pool.release(obj)

// Enhanced stats (NEW)
const stats = pool.getStats()
// { poolSize, maxSize, createdCount, availableCount, inUseCount, acquireCount, releaseCount, utilizationRate }

Enhanced WeakCache ​

typescript
import { WeakCache } from 'directix'

const cache = new WeakCache<HTMLElement, any>(50)

cache.set(element, { computed: true })
cache.get(element)

// NEW: Cache statistics with hit rate
const stats = cache.getStats()
// { hitCount, missCount, hitRate, strongCacheSize, maxStrongSize }

Released under the MIT License.