diff --git a/CHANGELOG.adoc b/CHANGELOG.adoc index 5667a143a64..1baa75ca795 100644 --- a/CHANGELOG.adoc +++ b/CHANGELOG.adoc @@ -112,7 +112,7 @@ A migration participant has been added to automatically keep compatible all diag - https://github.com/eclipse-sirius/sirius-web/issues/3392[#3392] [diagram] Prevent edge from passing through another node - https://github.com/eclipse-sirius/sirius-web/issues/3763[#3763] [diagram] Split the SelectionDialogDescription to prepare the Tree support - https://github.com/eclipse-sirius/sirius-web/issues/3793[#3793] [sirius-web] Add mechanism to retrieve the parent object of an element in the tree representation - +- https://github.com/eclipse-sirius/sirius-web/issues/3887[#3887] [diagram] Memoize diagram representation (improve performance when selecting an element on large diagram) == v2024.7.0 diff --git a/packages/diagrams/frontend/sirius-components-diagrams/src/representation/DiagramRepresentation.tsx b/packages/diagrams/frontend/sirius-components-diagrams/src/representation/DiagramRepresentation.tsx index a5ff0b9619f..37202829001 100644 --- a/packages/diagrams/frontend/sirius-components-diagrams/src/representation/DiagramRepresentation.tsx +++ b/packages/diagrams/frontend/sirius-components-diagrams/src/representation/DiagramRepresentation.tsx @@ -13,7 +13,7 @@ import { gql, OnDataOptions, useQuery, useSubscription } from '@apollo/client'; import { RepresentationComponentProps, useMultiToast } from '@eclipse-sirius/sirius-components-core'; -import { useEffect, useState } from 'react'; +import { memo, useEffect, useState } from 'react'; import { ReactFlowProvider } from 'reactflow'; import { DiagramContext } from '../contexts/DiagramContext'; import { DiagramDescriptionContext } from '../contexts/DiagramDescriptionContext'; @@ -78,131 +78,129 @@ export const getDiagramDescription = gql` const isDiagramRefreshedEventPayload = (payload: GQLDiagramEventPayload): payload is GQLDiagramRefreshedEventPayload => payload.__typename === 'DiagramRefreshedEventPayload'; -export const DiagramRepresentation = ({ - editingContextId, - representationId, - readOnly, -}: RepresentationComponentProps) => { - const [state, setState] = useState({ - id: crypto.randomUUID(), - diagramRefreshedEventPayload: null, - payload: null, - complete: false, - message: null, - }); - const { addErrorMessage } = useMultiToast(); +export const DiagramRepresentation = memo( + ({ editingContextId, representationId, readOnly }: RepresentationComponentProps) => { + const [state, setState] = useState({ + id: crypto.randomUUID(), + diagramRefreshedEventPayload: null, + payload: null, + complete: false, + message: null, + }); + const { addErrorMessage } = useMultiToast(); - const variables: GQLDiagramEventVariables = { - input: { - id: state.id, - editingContextId, - diagramId: representationId, - }, - }; + const variables: GQLDiagramEventVariables = { + input: { + id: state.id, + editingContextId, + diagramId: representationId, + }, + }; - const onData = ({ data }: OnDataOptions) => { - if (data.data) { - const { diagramEvent } = data.data; - if (isDiagramRefreshedEventPayload(diagramEvent)) { - setState((prevState) => ({ ...prevState, diagramRefreshedEventPayload: diagramEvent })); + const onData = ({ data }: OnDataOptions) => { + if (data.data) { + const { diagramEvent } = data.data; + if (isDiagramRefreshedEventPayload(diagramEvent)) { + setState((prevState) => ({ ...prevState, diagramRefreshedEventPayload: diagramEvent })); + } + setState((prevState) => ({ ...prevState, payload: diagramEvent })); } - setState((prevState) => ({ ...prevState, payload: diagramEvent })); - } - }; + }; - const { - loading: diagramDescriptionLoading, - data: diagramDescriptionData, - error: diagramDescriptionError, - } = useQuery(getDiagramDescription, { - variables: { - editingContextId, - representationId, - }, - skip: state.diagramRefreshedEventPayload === null, - }); + const { + loading: diagramDescriptionLoading, + data: diagramDescriptionData, + error: diagramDescriptionError, + } = useQuery(getDiagramDescription, { + variables: { + editingContextId, + representationId, + }, + skip: state.diagramRefreshedEventPayload === null, + }); - useEffect(() => { - if (!diagramDescriptionLoading) { - setState((prevState) => ({ - ...prevState, - diagramDescription: diagramDescriptionData?.viewer.editingContext.representation.description, - })); - } - if (diagramDescriptionError) { - const { message } = diagramDescriptionError; - addErrorMessage(message); - } - }, [diagramDescriptionLoading, diagramDescriptionData, diagramDescriptionError]); + useEffect(() => { + if (!diagramDescriptionLoading) { + setState((prevState) => ({ + ...prevState, + diagramDescription: diagramDescriptionData?.viewer.editingContext.representation.description, + })); + } + if (diagramDescriptionError) { + const { message } = diagramDescriptionError; + addErrorMessage(message); + } + }, [diagramDescriptionLoading, diagramDescriptionData, diagramDescriptionError]); - const onComplete = () => { - setState((prevState) => ({ ...prevState, diagramRefreshedEventPayload: null, complete: true })); - }; + const onComplete = () => { + setState((prevState) => ({ ...prevState, diagramRefreshedEventPayload: null, complete: true })); + }; - const { error } = useSubscription(subscription, { - variables, - fetchPolicy: 'no-cache', - onData, - onComplete, - }); + const { error } = useSubscription(subscription, { + variables, + fetchPolicy: 'no-cache', + onData, + onComplete, + }); - const diagramDescription: GQLDiagramDescription | undefined = - diagramDescriptionData?.viewer.editingContext.representation.description; + const diagramDescription: GQLDiagramDescription | undefined = + diagramDescriptionData?.viewer.editingContext.representation.description; - if (state.message) { - return
{state.message}
; - } - if (error) { - return
{error.message}
; - } - if (state.complete) { - return
The representation is not available anymore
; - } - if (!state.diagramRefreshedEventPayload || !diagramDescription) { - return
; - } + if (state.message) { + return
{state.message}
; + } + if (error) { + return
{error.message}
; + } + if (state.complete) { + return
The representation is not available anymore
; + } + if (!state.diagramRefreshedEventPayload || !diagramDescription) { + return
; + } - return ( - - - - - - - - - - -
- - - - - - -
-
-
-
-
-
-
-
-
-
-
- ); -}; + return ( + + + + + + + + + + +
+ + + + + + +
+
+
+
+
+
+
+
+
+
+
+ ); + } +);