docs/solutions/performance-issues/2026-05-01-slate-v2-large-document-shell-policy-must-be-explicit-and-corridor-mounted.md
Slate v2's large-document shell path was doing useful work, but the API and corridor semantics were lying. enabled: true made shell virtualization read like the general large-document default, and activeRadius could mark islands active without mounting their editable descendants.
largeDocument={{ enabled: true }} hid the real policy choice: safe DOM-present grouping versus aggressive shell virtualization.createIslandPlan set isActive for radius-neighbor islands but only mounted one top-level runtime id from the center island.enabled optimization. That blurred the line between a safe default and an aggressive mode with browser selection, find, accessibility, clipboard, IME, and mobile risks.activeRadius as metadata only. A corridor that does not mount its active islands is not a corridor.Make shell mode explicit and make active islands actually mount.
Before:
type LargeDocumentOptions = {
activeRadius?: number
enabled?: boolean
islandSize?: number
previewChars?: number
threshold?: number
}
After:
type LargeDocumentMode = 'auto' | 'dom-present' | 'off' | 'shell'
type LargeDocumentOptions =
| LargeDocumentMode
| {
activeRadius?: number
islandSize?: number
mode: 'shell'
previewChars?: number
threshold?: number
}
The render policy is now honest:
largeDocument="auto": safe DOM-present grouping;largeDocument="dom-present": force the safe DOM-present layer;largeDocument="off": disable automatic root grouping;largeDocument={{ mode: 'shell', ... }}: opt into aggressive shell virtualization.Fix corridor mounting in createIslandPlan:
const isActive = islandIndex >= activeStart && islandIndex <= activeEnd
const runtimeIds = topLevelRuntimeIds.slice(startIndex, endIndex + 1)
islands.push({
isActive,
mountedRuntimeIds: isActive ? runtimeIds : [],
runtimeIds,
// ...
})
Also fail closed during composition in LargeDocumentIslandShell:
event.preventDefault()
if (IS_COMPOSING.get(editor)) {
return
}
onPromote?.(islandIndex, { select: true })
The API now says what the runtime does. DOM-present grouping is the safe default; shell mode is an explicit aggressive choice.
The selection and reconciliation layers can also trust the mounted ranges again. If an island is active, all its top-level runtime ids are mounted. If it is inactive, it is a shell. There is no half-active state where model logic believes content is mounted but React renders only one block.
Composition is treated as a hard boundary. Shell promotion during IME can move focus and selection under the browser's composition machinery, so the shell should ignore activation until composition ends.
enabled.active, the active content must exist in the DOM or the API should be renamed.auto groups DOM-present roots;dom-present explicitly groups;off disables grouping;{ mode: 'shell' } shells far islands.IS_COMPOSING is true.