Safari 18.6: Layout thrashing during editing with large stylesheets
OS: macOS 15.0 · Device: Desktop Any · Browser: Safari 18.6 · Keyboard: Any
Open case →Scenario
Managing exponential slowdowns in large documents and browser-specific engine thrashing.
Contenteditable editors degrade exponentially as content grows. Scaling to 10k+ characters requires moving away from native DOM traversal towards structured indexing and virtualization.
Mobile Safari 18.6 exhibits $O(n^2)$ complexity when joining RuleSets for attribute selectors.
Operations like window.getSelection().addRange() become progressively slower as the DOM depth increases.
Pasting large blocks or performing rapid UNDO operations can leave thousands of detached nodes in memory if event listeners aren’t strictly managed.
Maintain a flat array of ‘text node’ metadata to perform O(1) character-to-node lookups, bypassing expensive TreeWalkers.
Avoid complex attribute selectors like [class*="editor-"] globally. Use unique class names to prevent the $O(n^2)$ invalidation path in WebKit.
Visual view of how this scenario connects to its concrete cases and environments. Nodes can be dragged and clicked.
Each row is a concrete case for this scenario, with a dedicated document and playground.
| Case | OS | Device | Browser | Keyboard | Status |
|---|---|---|---|---|---|
| ce-0578 | macOS 15.0 | Desktop Any | Safari 18.6 | Any | confirmed |
Open a case to see the detailed description and its dedicated playground.
OS: macOS 15.0 · Device: Desktop Any · Browser: Safari 18.6 · Keyboard: Any
Open case →Other scenarios that share similar tags or category.
When a contenteditable element has CSS filters applied (blur, brightness, etc.), editing performance may be degraded. Typing may lag, and selection may be slow to update.
When a contenteditable element has CSS will-change property set, performance may be affected. In some cases, it may improve performance by hinting the browser about upcoming changes. In other cases, it may degrade performance by creating unnecessary layers.
When a MutationObserver is attached to a contenteditable element or its parent, the observer callbacks may interfere with editing performance. Frequent DOM mutations during typing can trigger many observer callbacks, causing lag or jank.
When a ResizeObserver is attached to a contenteditable element, the observer may trigger during editing as content changes size. This can cause layout recalculations and visual jumps, especially when the contenteditable has dynamic height.
When a contenteditable element is used with virtual scrolling libraries (e.g., for large documents), the virtual scrolling mechanism may interfere with text selection and caret positioning. The selection may be lost when elements are removed from the DOM during scrolling.
Have questions, suggestions, or want to share your experience? Join the discussion below.