From 36d477e5f51971250a6a10643e1a71be13c7b8d6 Mon Sep 17 00:00:00 2001 From: Ivan Starkov Date: Tue, 14 May 2024 19:19:04 +0300 Subject: [PATCH] fix: Slow performance on a large site during text editing (#3351) ## Description Update edited element on blur https://fast-canvas-edit.development.webstudio.is/builder/ab3439dc-8eab-4050-a5b4-71247fba7d4c ## Steps for reproduction 1. click button 2. expect xyz ## Code Review - [ ] hi @kof, I need you to do - conceptual review (architecture, feature-correctness) - detailed review (read every line) - test it on preview ## Before requesting a review - [ ] made a self-review - [ ] added inline comments where things may be not obvious (the "why", not "what") ## Before merging - [ ] tested locally and on preview environment (preview dev login: 5de6) - [ ] updated [test cases](https://github.com/webstudio-is/webstudio/blob/main/apps/builder/docs/test-cases.md) document - [ ] added tests - [ ] if any new env variables are added, added them to `.env.example` and the `builder/env-check.js` if mandatory --- .../features/text-editor/text-editor.tsx | 30 +++++++++++++++++-- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/apps/builder/app/canvas/features/text-editor/text-editor.tsx b/apps/builder/app/canvas/features/text-editor/text-editor.tsx index c05c319680f3..95f5b9482360 100644 --- a/apps/builder/app/canvas/features/text-editor/text-editor.tsx +++ b/apps/builder/app/canvas/features/text-editor/text-editor.tsx @@ -8,6 +8,7 @@ import { $createLineBreakNode, $getSelection, $isRangeSelection, + type EditorState, } from "lexical"; import { LinkNode } from "@lexical/link"; import { LexicalComposer } from "@lexical/react/LexicalComposer"; @@ -15,7 +16,6 @@ import { useLexicalComposerContext } from "@lexical/react/LexicalComposerContext import { RichTextPlugin } from "@lexical/react/LexicalRichTextPlugin"; import LexicalErrorBoundary from "@lexical/react/LexicalErrorBoundary"; import { HistoryPlugin } from "@lexical/react/LexicalHistoryPlugin"; -import { OnChangePlugin } from "@lexical/react/LexicalOnChangePlugin"; import { LinkPlugin } from "@lexical/react/LexicalLinkPlugin"; import { nanoid } from "nanoid"; import { createRegularStyleSheet } from "@webstudio-is/css-engine"; @@ -30,6 +30,7 @@ import { $convertTextToLexical, } from "./interop"; import { colord } from "colord"; +import { useEffectEvent } from "~/shared/hook-utils/effect-event"; const BindInstanceToNodePlugin = ({ refs }: { refs: Refs }) => { const [editor] = useLexicalComposerContext(); @@ -113,6 +114,29 @@ const CaretColorPlugin = () => { return null; }; +const OnChangeOnBlurPlugin = ({ + onChange, +}: { + onChange: (editorState: EditorState) => void; +}) => { + const [editor] = useLexicalComposerContext(); + const handleChange = useEffectEvent(onChange); + + useEffect(() => { + const handleBlur = () => { + handleChange(editor.getEditorState()); + }; + + // https://github.com/facebook/lexical/blob/867d449b2a6497ff9b1fbdbd70724c74a1044d8b/packages/lexical-react/src/LexicalNodeEventPlugin.ts#L59C12-L67C8 + return editor.registerRootListener((rootElement, prevRootElement) => { + rootElement?.addEventListener("blur", handleBlur); + prevRootElement?.removeEventListener("blur", handleBlur); + }); + }, [editor, handleChange]); + + return null; +}; + const RemoveParagaphsPlugin = () => { const [editor] = useLexicalComposerContext(); @@ -266,8 +290,8 @@ export const TextEditor = ({ /> - { editorState.read(() => { const treeRootInstance = instances.get(rootInstanceSelector[0]);