Hi, I’ve encountered a performance bottleneck in my document, which contains numerous tables. Whenever I useNodeView for rendering ProseMirror tables, any state update triggers a re-rendering of the tables. This is causing significant issues. I’ve noticed that the update()
function within NodeView is being called. How can I address this?
import { render, unmountComponentAtNode } from "react-dom";
import { EditorView, Decoration } from "prosemirror-view";
import { Node as ProsemirrorNode } from "prosemirror-model";
import Editor from "../";
import { v4 as uuid4 } from "uuid";
// type
import type { NodeViewComponentFunc } from "../types/node-view/base-node-view";
type Options = {
editor: Editor;
node: ProsemirrorNode;
view: EditorView;
getPos: () => number;
decorations: Decoration[];
options?: Record<string, any>;
};
export default class NodeViewBase {
component: NodeViewComponentFunc | null;
editor: Editor;
node: ProsemirrorNode;
view: EditorView;
getPos: () => number;
decorations: Decoration[];
isSelected = false;
dom: HTMLElement | null;
uuid: string;
options?: Record<string, any>;
constructor(
component: NodeViewComponentFunc | null,
{ editor, node, view, getPos, decorations, options = undefined }: Options
) {
this.component = component;
this.editor = editor;
this.getPos = getPos;
this.decorations = decorations;
this.node = node;
this.view = view;
this.uuid = uuid4();
this.options = options;
}
renderElement(call?: () => void, container?: HTMLElement) {
if (!this.component) return;
const children = this.component({
node: this.node,
isSelected: this.isSelected,
isEditable:
!this.editor.props.readOnly && !this.editor.props.previewHistoryVersion,
editor: this.editor,
uuid: this.uuid,
getPos: this.getPos,
options: this.options,
});
render(children, container ?? this.dom, call);
}
update(node: ProsemirrorNode) {
if (node.type !== this.node.type) {
return false;
}
this.node = node;
this.renderElement();
return true;
}
selectNode() {
if (this.view.editable) {
this.isSelected = true;
this.renderElement();
}
}
deselectNode() {
if (this.view.editable) {
this.isSelected = false;
this.renderElement();
}
}
stopEvent() {
return false;
}
destroy() {
if (this.dom) {
unmountComponentAtNode(this.dom);
}
this.dom = null;
}
ignoreMutation() {
return true;
}
}