Skip to content

Commit

Permalink
perf(react): do some light diffing to not reset options on every render
Browse files Browse the repository at this point in the history
  • Loading branch information
nperez0111 committed Jan 17, 2025
1 parent 839eb47 commit 5bc3c67
Showing 1 changed file with 36 additions and 6 deletions.
42 changes: 36 additions & 6 deletions packages/react/src/useEditor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,33 @@ class EditorInstanceManager {
}
}

static compareOptions(a: UseEditorOptions, b: UseEditorOptions) {
return (Object.keys(a) as (keyof UseEditorOptions)[]).every(key => {
if (['onCreate', 'onBeforeCreate', 'onDestroy', 'onUpdate', 'onTransaction', 'onFocus', 'onBlur', 'onSelectionUpdate', 'onContentError', 'onDrop', 'onPaste'].includes(key)) {
// we don't want to compare callbacks, they are always different and only registered once
return true
}

// We often encourage putting extensions inlined in the options object, so we will do a slightly deeper comparison here
if (key === 'extensions' && a.extensions && b.extensions) {
if (a.extensions.length !== b.extensions.length) {
return false
}
return a.extensions.every((extension, index) => {
if (extension !== b.extensions?.[index]) {
return false
}
return true
})
}
if (a[key] !== b[key]) {
// if any of the options have changed, we should update the editor options
return false
}
return true
})
}

/**
* On each render, we will create, update, or destroy the editor instance.
* @param deps The dependencies to watch for changes
Expand All @@ -197,12 +224,15 @@ class EditorInstanceManager {
clearTimeout(this.scheduledDestructionTimeout)

if (this.editor && !this.editor.isDestroyed && deps.length === 0) {
// if the editor does exist & deps are empty, we don't need to re-initialize the editor
// we can fast-path to update the editor options on the existing instance
this.editor.setOptions({
...this.options.current,
editable: this.editor.isEditable,
})
// if the editor does exist & deps are empty, we don't need to re-initialize the editor generally
if (!EditorInstanceManager.compareOptions(this.options.current, this.editor.options)) {
// But, the options are different, so we need to update the editor options
// Still, this is faster than re-creating the editor
this.editor.setOptions({
...this.options.current,
editable: this.editor.isEditable,
})
}
} else {
// When the editor:
// - does not yet exist
Expand Down

0 comments on commit 5bc3c67

Please sign in to comment.