Skip to content

ObjectPool

The ObjectPool manages a cache of DOM elements keyed by tag name. It reduces garbage collection pressure by reusing elements instead of creating and discarding them during rapid streaming updates.

Import

The ObjectPool is not imported directly. Plugins access it through the PluginContext and RenderContext objects.

Interface

ts
interface ObjectPool {
  /** Get an element from the pool or create a new one for the given tag. */
  acquire(tag: string): HTMLElement;

  /** Return an element to the pool after clearing attributes, children, and listeners. */
  release(element: HTMLElement): void;

  /** Empty the pool completely, allowing all pooled elements to be garbage-collected. */
  drain(): void;

  /** Return a snapshot of pool statistics for testing and debugging. */
  stats(): ObjectPoolStats;
}

interface ObjectPoolStats {
  /** Number of elements currently in the pool, available for reuse. */
  pooled: number;

  /** Number of elements that have been acquired but not yet released. */
  active: number;

  /** Total number of elements created since the pool was instantiated. */
  created: number;

  /** Total number of times an element was reused instead of created. */
  reused: number;
}

Methods

acquire

ts
acquire(tag: string): HTMLElement

Returns an element for the given tag name. If the pool has a recycled element of that type, it is returned. Otherwise, a new element is created via document.createElement.

Plugins should use ctx.createElement(tag) in render(), which delegates to the pool internally.

release

ts
release(element: HTMLElement): void

Returns an element to the pool. Before storing it, the pool:

  1. Removes all attributes
  2. Removes all child nodes
  3. Removes all event listeners (via clone-and-replace or tracking)
  4. Resets className

If the pool for this tag is already at capacity (100 elements per tag), the element is not stored and is left for garbage collection.

drain

ts
drain(): void

Empties the entire pool. All stored elements are released for garbage collection. Called automatically by GenerativeDom.destroy().

stats

ts
stats(): ObjectPoolStats

Returns a snapshot of the pool's current statistics. Useful for testing, debugging, and monitoring performance.

Usage in Plugins

Plugins interact with the pool through the render context:

ts
render(token: Token, ctx: RenderContext): HTMLElement {
  // ctx.createElement uses the pool internally
  const el = ctx.createElement('blockquote');
  const inner = ctx.createText(token.content ?? '');
  el.appendChild(inner);
  return el;
}

The core handles releasing elements back to the pool when tokens are removed from the AST. Plugins do not need to call release() directly unless they manage additional elements outside the normal render flow.

Configuration

The pool stores up to 100 elements per tag name. This limit is not currently configurable through the public API. Elements beyond this limit are discarded normally.

Monitoring

ts
const md = new GenerativeDom({ container: el, plugins: [...] });

// After some rendering...
const stats = md.pool.stats();
console.log(`Pooled: ${stats.pooled}`);
console.log(`Active: ${stats.active}`);
console.log(`Created: ${stats.created}`);
console.log(`Reused: ${stats.reused}`);
console.log(`Reuse ratio: ${(stats.reused / stats.created * 100).toFixed(1)}%`);

A reuse ratio of zero after multiple reset/render cycles may indicate that element recycling is not working as expected.