From 6363492cee07065a59daa8f55b4c62b14b164ddc Mon Sep 17 00:00:00 2001 From: David Luzar <5153846+dwelle@users.noreply.github.com> Date: Fri, 10 Nov 2023 16:13:08 +0100 Subject: [PATCH] fix: perf issue when ungrouping elements within frame (#7265) Co-authored-by: Ryan Di --- src/actions/actionGroup.tsx | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/src/actions/actionGroup.tsx b/src/actions/actionGroup.tsx index 8ee84ac7..219f1444 100644 --- a/src/actions/actionGroup.tsx +++ b/src/actions/actionGroup.tsx @@ -17,15 +17,12 @@ import { import { getNonDeletedElements } from "../element"; import { randomId } from "../random"; import { ToolButton } from "../components/ToolButton"; -import { - ExcalidrawElement, - ExcalidrawFrameElement, - ExcalidrawTextElement, -} from "../element/types"; +import { ExcalidrawElement, ExcalidrawTextElement } from "../element/types"; import { AppClassProperties, AppState } from "../types"; import { isBoundToContainer } from "../element/typeChecks"; import { getElementsInResizingFrame, + getFrameElements, groupByFrames, removeElementsFromFrame, replaceAllElementsInFrame, @@ -190,13 +187,6 @@ export const actionUngroup = register({ let nextElements = [...elements]; - const selectedElements = app.scene.getSelectedElements(appState); - const frames = selectedElements - .filter((element) => element.frameId) - .map((element) => - app.scene.getElement(element.frameId!), - ) as ExcalidrawFrameElement[]; - const boundTextElementIds: ExcalidrawTextElement["id"][] = []; nextElements = nextElements.map((element) => { if (isBoundToContainer(element)) { @@ -221,7 +211,19 @@ export const actionUngroup = register({ null, ); - frames.forEach((frame) => { + const selectedElements = app.scene.getSelectedElements(appState); + + const selectedElementFrameIds = new Set( + selectedElements + .filter((element) => element.frameId) + .map((element) => element.frameId!), + ); + + const targetFrames = getFrameElements(elements).filter((frame) => + selectedElementFrameIds.has(frame.id), + ); + + targetFrames.forEach((frame) => { if (frame) { nextElements = replaceAllElementsInFrame( nextElements,