diff --git a/frontend/src/components/editor/Preview.tsx b/frontend/src/components/editor/Preview.tsx index 40b5eee8..25d0c364 100644 --- a/frontend/src/components/editor/Preview.tsx +++ b/frontend/src/components/editor/Preview.tsx @@ -2,7 +2,7 @@ import { CircularProgress, Stack } from "@mui/material"; import MarkdownPreview from "@uiw/react-markdown-preview"; import katex from "katex"; import "katex/dist/katex.min.css"; -import { useEffect, useState } from "react"; +import { useCallback, useEffect, useState } from "react"; import { useSelector } from "react-redux"; import rehypeExternalLinks from "rehype-external-links"; import rehypeKatex from "rehype-katex"; @@ -13,25 +13,36 @@ import { useCurrentTheme } from "../../hooks/useCurrentTheme"; import { selectEditor } from "../../store/editorSlice"; import { addSoftLineBreak } from "../../utils/document"; import "./editor.css"; +import _ from "lodash"; + +const DELAY = 500; function Preview() { const currentTheme = useCurrentTheme(); const editorStore = useSelector(selectEditor); const [content, setContent] = useState(""); + const throttledUpdatePreviewConetent = useCallback( + _.throttle( + () => { + const editorText = editorStore.doc?.getRoot().content?.toString() || ""; + + // Add soft line break + setContent(addSoftLineBreak(editorText)); + }, + DELAY, + // Set trailing true to prevent ignoring last call + { trailing: true } + ), + [] + ); useEffect(() => { if (!editorStore.doc) return; - const updatePreviewContent = () => { - const editorText = editorStore.doc?.getRoot().content?.toString() || ""; - // Add soft line break - setContent(addSoftLineBreak(editorText)); - }; - - updatePreviewContent(); + throttledUpdatePreviewConetent(); const unsubsribe = editorStore.doc.subscribe("$.content", () => { - updatePreviewContent(); + throttledUpdatePreviewConetent(); }); return () => {