Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 80e53ef03c |
@@ -0,0 +1,4 @@
|
|||||||
|
## 2024-06-07 - Memoize callbacks passed to Excalidraw
|
||||||
|
|
||||||
|
**Learning:** Due to the exceptionally high rendering cost of the `@excalidraw/excalidraw` canvas, always ensure all callbacks passed to it (e.g., `onExcalidrawAPI`) are strictly memoized using `useCallback`. Passing inline functions as props breaks prop stability for `React.memo` and causes severe UI input lag caused by full canvas re-renders when parent states change.
|
||||||
|
**Action:** When working with `<Excalidraw>` or its wrapper components like `<EditorCanvas>`, always extract inline callback functions (like `onExcalidrawAPI={(api) => { ... }}`) into `useCallback` hooks before passing them down.
|
||||||
@@ -307,6 +307,9 @@ function PrivateApp() {
|
|||||||
[],
|
[],
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// ⚡ Bolt: Memoize the Excalidraw API callback to prevent EditorCanvas from re-rendering
|
||||||
|
// Excalidraw has exceptionally high rendering cost, so we must maintain prop stability
|
||||||
|
// for EditorCanvas's React.memo to avoid severe UI input lag on any parent state change.
|
||||||
const handleExcalidrawAPI = useCallback((api: ExcalidrawImperativeAPI) => {
|
const handleExcalidrawAPI = useCallback((api: ExcalidrawImperativeAPI) => {
|
||||||
excalidrawApiRef.current = api;
|
excalidrawApiRef.current = api;
|
||||||
}, []);
|
}, []);
|
||||||
|
|||||||
@@ -30,24 +30,20 @@ function CodeBlockEditor({
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
let cancelled = false;
|
let cancelled = false;
|
||||||
|
void renderHighlightedCodeBlockHtml(draft.code, draft.language)
|
||||||
const timeoutId = setTimeout(() => {
|
.then((nextHtml) => {
|
||||||
void renderHighlightedCodeBlockHtml(draft.code, draft.language)
|
if (!cancelled) {
|
||||||
.then((nextHtml) => {
|
setHtml(nextHtml);
|
||||||
if (!cancelled) {
|
}
|
||||||
setHtml(nextHtml);
|
})
|
||||||
}
|
.catch(() => {
|
||||||
})
|
if (!cancelled) {
|
||||||
.catch(() => {
|
setHtml(null);
|
||||||
if (!cancelled) {
|
}
|
||||||
setHtml(null);
|
});
|
||||||
}
|
|
||||||
});
|
|
||||||
}, 100);
|
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
cancelled = true;
|
cancelled = true;
|
||||||
clearTimeout(timeoutId);
|
|
||||||
};
|
};
|
||||||
}, [draft.code, draft.language]);
|
}, [draft.code, draft.language]);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user