feat: improve library sidebar performance (#9060)

Co-authored-by: dwelle <5153846+dwelle@users.noreply.github.com>
pull/9070/head
Are 4 weeks ago committed by GitHub
parent bd1590fc74
commit 61e0bb83d0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -1,4 +1,10 @@
import React, { useState, useCallback, useMemo, useRef } from "react"; import React, {
useState,
useCallback,
useMemo,
useRef,
useEffect,
} from "react";
import type Library from "../data/library"; import type Library from "../data/library";
import { import {
distributeLibraryItemsOnSquareGrid, distributeLibraryItemsOnSquareGrid,
@ -150,27 +156,40 @@ const usePendingElementsMemo = (
appState: UIAppState, appState: UIAppState,
elements: readonly NonDeletedExcalidrawElement[], elements: readonly NonDeletedExcalidrawElement[],
) => { ) => {
const create = () => const create = useCallback(
getSelectedElements(elements, appState, { (appState: UIAppState, elements: readonly NonDeletedExcalidrawElement[]) =>
includeBoundTextElement: true, getSelectedElements(elements, appState, {
includeElementsInFrames: true, includeBoundTextElement: true,
}); includeElementsInFrames: true,
const val = useRef(create()); }),
[],
);
const val = useRef(create(appState, elements));
const prevAppState = useRef<UIAppState>(appState); const prevAppState = useRef<UIAppState>(appState);
const prevElements = useRef(elements); const prevElements = useRef(elements);
if ( const update = useCallback(() => {
!isShallowEqual( if (
appState.selectedElementIds, !isShallowEqual(
prevAppState.current.selectedElementIds, appState.selectedElementIds,
) || prevAppState.current.selectedElementIds,
!isShallowEqual(elements, prevElements.current) ) ||
) { !isShallowEqual(elements, prevElements.current)
val.current = create(); ) {
prevAppState.current = appState; val.current = create(appState, elements);
prevElements.current = elements; prevAppState.current = appState;
} prevElements.current = elements;
return val.current; }
}, [create, appState, elements]);
return useMemo(
() => ({
update,
value: val.current,
}),
[update, val],
);
}; };
/** /**
@ -181,6 +200,7 @@ export const LibraryMenu = () => {
const { library, id, onInsertElements } = useApp(); const { library, id, onInsertElements } = useApp();
const appProps = useAppProps(); const appProps = useAppProps();
const appState = useUIAppState(); const appState = useUIAppState();
const app = useApp();
const setAppState = useExcalidrawSetAppState(); const setAppState = useExcalidrawSetAppState();
const elements = useExcalidrawElements(); const elements = useExcalidrawElements();
const [selectedItems, setSelectedItems] = useState<LibraryItem["id"][]>([]); const [selectedItems, setSelectedItems] = useState<LibraryItem["id"][]>([]);
@ -203,9 +223,13 @@ export const LibraryMenu = () => {
}); });
}, [setAppState]); }, [setAppState]);
useEffect(() => {
return app.onPointerUpEmitter.on(() => pendingElements.update());
}, [app, pendingElements]);
return ( return (
<LibraryMenuContent <LibraryMenuContent
pendingElements={pendingElements} pendingElements={pendingElements.value}
onInsertLibraryItems={onInsertLibraryItems} onInsertLibraryItems={onInsertLibraryItems}
onAddToLibrary={deselectItems} onAddToLibrary={deselectItems}
setAppState={setAppState} setAppState={setAppState}

@ -681,6 +681,8 @@ export type AppClassProperties = {
getEditorUIOffsets: App["getEditorUIOffsets"]; getEditorUIOffsets: App["getEditorUIOffsets"];
visibleElements: App["visibleElements"]; visibleElements: App["visibleElements"];
excalidrawContainerValue: App["excalidrawContainerValue"]; excalidrawContainerValue: App["excalidrawContainerValue"];
onPointerUpEmitter: App["onPointerUpEmitter"];
}; };
export type PointerDownState = Readonly<{ export type PointerDownState = Readonly<{

Loading…
Cancel
Save