Performance
How Echo Editor stays fast and how to keep your integration fast.
What the editor does for you
| Technique | Effect |
|---|---|
| Shared dependencies | Tiptap, ProseMirror, Vue and the UI primitives are dependencies, not bundled. The main entry is ~49 KB gzipped (down from ~437 KB in 0.x) and your app keeps a single copy of Tiptap. |
| Lazy feature UIs | Link / table / image / column menus, the AI menu, menubar, dialogs (preview, source code, special characters) and find & replace are separate chunks, downloaded only when their extension is registered or the dialog is first opened. |
| Lazy syntax highlighting | prism-code-editor and its grammars (~26 KB gzipped) load on the first code block. |
| Lazy languages | Only English and Chinese are bundled; other languages are fetched on demand. |
| Frame-batched toolbar | Toolbar and bubble-menu state are recomputed at most once per animation frame, only for transactions that change the document, selection or stored marks — not on every reactive tick. |
| Cheap v-model | Serialising is throttled (200 ms, flushed on blur), echoes of the emitted value are detected without re-serialising, and deep watchers are avoided. |
| Batched streaming | AI responses render once per frame; code blocks write back to the document in batches. |
| Per-editor state | No global listeners per component: theme, locale and stores are shared or scoped. |
Tips for your app
Create extensions once
The extension list is read when the editor is created; to switch sets, remount with a key.
Use useEditorState for custom UI
Reading editor.state in a computed re-runs on every transaction. useEditorState evaluates once per frame and only when something relevant changed:
Prefer JSON for large documents
getJSON() is cheaper than getHTML(), and JSON round-trips losslessly. Use output="json" for very large documents and render HTML on the server when needed.
Register only what you use
Each extension adds schema, plugins and a toolbar control. The minimal preset is a good starting point.
Keep v-model handlers light
Don't send every update to the server — debounce saves or save on blur: