Recently, we optimized the rendering performance of Tiptap based on community feedback. We found that the editor was re-rendering more often than necessary, causing performance issues in larger applications. With Tiptap 2.5, you now have greater control over the editor’s rendering behavior.
New rendering features
We've now given you more control over rendering behavior by introducing two new options:
immediatelyRender
Previously, on first render, the editor was not available for compatibility with SSR. Now, with this option, it creates the editor immediately upon first render, eliminating a flickering as the editor initialized.
shouldRerenderOnTransaction
This option ensures the Editor only re-renders when necessary, such as when a styling change occurs. Previously, Tiptap would re-render on every keystroke, caret position change, and selection change. With this option, the editor only reloads when it truly needs to in React, significantly improving performance.
Here is an example of how you can use these options:
import { useEditor } from '@tiptap/react'
import deepEqual from 'deep-equal'
function Component() {
const editor = useEditor({
extensions,
content,
/**
* This option gives us the control to enable the default behavior of rendering the editor immediately.
*/
immediatelyRender: true,
/**
* This option gives us the control to disable the default behavior of re-rendering the editor on every transaction.
*/
shouldRerenderOnTransaction: false,
})
const editorState = useEditorState({
editor,
// This function will be called every time the editor state changes
selector: ({ editor: editorInstance }: { editor: Editor }) => ({
// It will only re-render if the bold or italic state changes
isBold: editorInstance.isActive('bold'),
isItalic: editorInstance.isActive('italic'),
}),
// This function will be used to compare the previous and the next state
equalityFn: deepEqual,
})
return (
<>
<EditorContent editor={editor} />
<button
onClick={() => editor.chain().focus().toggleBold().run()}
className={editorState.isBold ? 'primary' : ''}
>
Bold
</button>
<button
onClick={() => editor.chain().focus().toggleItalic().run()}
className={editorState.isItalic ? 'primary' : ''}
>
Italic
</button>
</>
)
}
Vue-specific improvements
For Vue 3 users, there was an issue where the selection state wouldn't update properly in certain cases, such as in a bubble menu. You would select text to format it differently, but the editor wouldn't catch up, staying one render behind. This issue has now been fixed, ensuring the editor updates fast enough to keep up with your selections.
For more information, please read the docs.
Thank you for your continued feedback and support!
Happy coding,
the Tiptap team