From zbeyens. The source code is available on GitHub.

Plate
PlatePliteEditorsTemplates
GitHub16kGitHub
DiscordDiscord
UNPUBLISHED
  • Overview
  • Why This Fork
  • Examples
Walkthroughs
  • Installing Plite
  • Adding Event Handlers
  • Defining Custom Elements
  • Applying Custom Formatting
  • Executing Commands
  • Saving to a Database
  • Canonical Change Substrate
  • Improving Performance
Concepts
  • Interfaces
  • Nodes
  • Locations
  • Transforms
  • Document Changes
  • Commands
  • Editor
  • Extensions
  • Rendering
  • Serializing
  • Normalizing
  • Using TypeScript
  • Roots
  • Document State
  • Editing Behavior
  • Selection And DOM
  • Clipboard And Paste
  • Projection And Overlays
  • Schema
API
  • Anchor API
  • Location API
  • Path API
  • PointEntry API
  • Point API
  • Range API
  • Selection API
  • Location Types APIs
  • Span API
  • Editor
  • Element API
  • NodeEntry API
  • Node API
  • Node Types APIs
  • Text API
  • Debug Value Scrubbing
  • Transforms API
Libraries
  • Plite DOM
  • History Editor API
  • History Extension Setup
  • History
  • Plite History
  • Plite Hyperscript
  • Plite Layout
  • Annotations
  • DOM Coverage Boundaries
  • Editable Component
  • Plite React Event Handling
  • Virtualized Rendering
  • Plite React Hooks
  • React Editor Setup
  • React Editor
  • Plite React
  • Plite Component
  • Plite Yjs
  • Plite
General
  • Migration
  • Contributing
  • Docs Proof Map
  • FAQ
  • Resources

Virtualized Rendering

PreviousNext

Use viewport-only mounting as an experimental stress path for pathological documents.

virtualized is an opt-in DOM strategy for pathological documents. It is experimental and not production-ready. Use it to measure and harden huge-document behavior without making ordinary editors give up native DOM coverage.

When To Use It

Use this mode only when a document is large enough that staged rendering and partial-DOM preview rendering still leave too much DOM or heap pressure.

StrategyUse it forProduction posture
autobounded large-document renderingproduction default
stagedeventual native DOM coverage for the whole document
Plite React Event HandlingPlite React Hooks

On This Page

When To Use ItUsageNative Behavior LimitsMetricsProduction Gate
Build your editor
Production-ready AI template and reusable components.
Get all-access
explicit product tradeoff
fulldebugging full DOM behaviordebug path
virtualizedviewport-only mounting for pathological documentsexperimental, not production-ready

This mode uses TanStack Virtual internally as the viewport range and measurement engine. Plite still owns selection, DOM coverage boundaries, model copy, and materialization policy.

For paginated editors, prefer page-level virtualization from @platejs/plite-layout. Page virtualization keeps page chrome, layout fragments, and selection projection under one mount boundary.

Usage

Virtualized rendering needs a bounded editable scroll surface. If Plite cannot prove that the editable root is a safe scroll owner, it falls back to staged rendering and reports the actual strategy through metrics.

auto uses bounded partial-DOM rendering for large documents. It does not background-mount the whole document.

<Editable
  domStrategy={{
    estimatedBlockSize: 32,
    overscan: 4,
    type: "virtualized",
    threshold: 25_000,
  }}
  style={{ height: 480, overflowY: "auto" }}
/>
<Editable
  domStrategy={{
    estimatedBlockSize: 32,
    overscan: 4,
    type: "virtualized",
    threshold: 25_000,
  }}
  style={{ height: 480, overflowY: "auto" }}
/>

The public API uses editor-shaped options. It does not expose TanStack's getScrollElement, measureElement, rangeExtractor, item-key hooks, or raw virtualizer options.

Native Behavior Limits

Unmounted content has no native DOM. That is the point of virtualization, and it is also the reason this mode stays experimental.

AreaCurrent behavior
Caret entryPlite materializes the target block before editing.
Broad selectionPlite keeps large selections in the model instead of expanding every block.
CopyPlite uses copyPolicy="model" for ranges crossing unmounted content.
Browser findNative find only sees mounted blocks.
Screen readersScreen readers only traverse mounted blocks.
IME and mobile selectionStill outside the production claim until raw-device proof exists.

Do not use this mode when the product requires native find, full screen-reader traversal, or production-grade mobile selection over the full document.

Metrics

Use onDOMStrategyMetrics whenever you test this mode. The callback tells you whether Plite actually used the requested strategy and how much DOM remains mounted.

<Editable
  domStrategy={{ type: "virtualized" }}
  onDOMStrategyMetrics={(metrics) => {
    navigator.sendBeacon(
      "/rum/plite-dom-strategy",
      JSON.stringify({
        degradationMode: metrics.degradationMode,
        documentSize: metrics.documentSize,
        domNodeCount: metrics.domNodeCount,
        effectiveStrategy: metrics.effectiveStrategy,
        mountedTopLevelCount: metrics.mountedTopLevelCount,
        pendingTopLevelCount: metrics.pendingTopLevelCount,
        requestedStrategy: metrics.requestedStrategy,
        viewportVirtualizationBoundaryCount:
          metrics.viewportVirtualizationBoundaryCount,
      })
    );
  }}
  style={{ height: 480, overflowY: "auto" }}
/>
<Editable
  domStrategy={{ type: "virtualized" }}
  onDOMStrategyMetrics={(metrics) => {
    navigator.sendBeacon(
      "/rum/plite-dom-strategy",
      JSON.stringify({
        degradationMode: metrics.degradationMode,
        documentSize: metrics.documentSize,
        domNodeCount: metrics.domNodeCount,
        effectiveStrategy: metrics.effectiveStrategy,
        mountedTopLevelCount: metrics.mountedTopLevelCount,
        pendingTopLevelCount: metrics.pendingTopLevelCount,
        requestedStrategy: metrics.requestedStrategy,
        viewportVirtualizationBoundaryCount:
          metrics.viewportVirtualizationBoundaryCount,
      })
    );
  }}
  style={{ height: 480, overflowY: "auto" }}

If effectiveStrategy is not virtualized, Plite is telling you that the virtualized path did not activate.

Production Gate

Keep this mode behind explicit product flags until these rows are green:

  • caret target materializes before every edit path;
  • copy and paste across unmounted ranges stay model-owned and correct;
  • IME composition does not lose text near virtualized boundaries;
  • mobile selection handles behave deterministically near mounted and unmounted edges;
  • browser find behavior is either custom-owned or explicitly limited;
  • screen-reader behavior has an accepted product strategy;
  • 25k and 50k document stress rows meet edit-latency budgets, not just ready time and DOM-count budgets.

See DOM Coverage Boundaries for the selection, copy, find, and materialization policies used at unmounted ranges.

/>