perf(editor): ⚡️ Improve graph transition perf
This commit is contained in:
@ -18,6 +18,7 @@ export const DrawingEdge = () => {
|
||||
sourceEndpoints,
|
||||
targetEndpoints,
|
||||
blocksCoordinates,
|
||||
graphOffsetY,
|
||||
} = useGraph()
|
||||
const { createEdge } = useTypebot()
|
||||
const [mousePosition, setMousePosition] = useState({ x: 0, y: 0 })
|
||||
@ -30,22 +31,20 @@ export const DrawingEdge = () => {
|
||||
const sourceTop = useMemo(() => {
|
||||
if (!connectingIds) return 0
|
||||
return getEndpointTopOffset(
|
||||
graphPosition,
|
||||
sourceEndpoints,
|
||||
graphOffsetY,
|
||||
connectingIds.source.itemId ?? connectingIds.source.stepId
|
||||
)
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [graphPosition, sourceEndpoints, connectingIds])
|
||||
}, [connectingIds, sourceEndpoints, graphOffsetY])
|
||||
|
||||
const targetTop = useMemo(() => {
|
||||
if (!connectingIds) return 0
|
||||
return getEndpointTopOffset(
|
||||
graphPosition,
|
||||
targetEndpoints,
|
||||
graphOffsetY,
|
||||
connectingIds.target?.stepId
|
||||
)
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [graphPosition, targetEndpoints, connectingIds])
|
||||
}, [connectingIds, targetEndpoints, graphOffsetY])
|
||||
|
||||
const path = useMemo(() => {
|
||||
if (!sourceTop || !sourceBlockCoordinates) return ``
|
||||
|
@ -24,7 +24,7 @@ export const DropOffEdge = ({
|
||||
onUnlockProPlanClick,
|
||||
}: Props) => {
|
||||
const { user } = useUser()
|
||||
const { sourceEndpoints, graphPosition, blocksCoordinates } = useGraph()
|
||||
const { sourceEndpoints, blocksCoordinates, graphOffsetY } = useGraph()
|
||||
const { publishedTypebot } = useTypebot()
|
||||
|
||||
const isUserOnFreePlan = isFreePlan(user)
|
||||
@ -59,13 +59,12 @@ export const DropOffEdge = ({
|
||||
const sourceTop = useMemo(
|
||||
() =>
|
||||
getEndpointTopOffset(
|
||||
graphPosition,
|
||||
sourceEndpoints,
|
||||
block?.steps[block.steps.length - 1].id,
|
||||
true
|
||||
graphOffsetY,
|
||||
block?.steps[block.steps.length - 1].id
|
||||
),
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
[block?.steps, graphPosition, sourceEndpoints, blocksCoordinates]
|
||||
[block?.steps, sourceEndpoints, blocksCoordinates]
|
||||
)
|
||||
|
||||
const labelCoordinates = useMemo(() => {
|
||||
|
@ -20,9 +20,8 @@ export const Edge = ({ edge }: { edge: EdgeProps }) => {
|
||||
previewingEdge,
|
||||
sourceEndpoints,
|
||||
targetEndpoints,
|
||||
graphPosition,
|
||||
blocksCoordinates,
|
||||
isReadOnly,
|
||||
graphOffsetY,
|
||||
} = useGraph()
|
||||
const isPreviewing = previewingEdge?.id === edge.id
|
||||
|
||||
@ -34,25 +33,27 @@ export const Edge = ({ edge }: { edge: EdgeProps }) => {
|
||||
const sourceTop = useMemo(
|
||||
() =>
|
||||
getEndpointTopOffset(
|
||||
graphPosition,
|
||||
sourceEndpoints,
|
||||
getSourceEndpointId(edge),
|
||||
isReadOnly
|
||||
graphOffsetY,
|
||||
getSourceEndpointId(edge)
|
||||
),
|
||||
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
[edge, graphPosition, sourceEndpoints, sourceBlockCoordinates?.y]
|
||||
[
|
||||
sourceBlockCoordinates?.x,
|
||||
sourceBlockCoordinates?.y,
|
||||
edge,
|
||||
sourceEndpoints,
|
||||
]
|
||||
)
|
||||
const targetTop = useMemo(
|
||||
() =>
|
||||
getEndpointTopOffset(
|
||||
graphPosition,
|
||||
targetEndpoints,
|
||||
edge?.to.stepId,
|
||||
isReadOnly
|
||||
),
|
||||
() => getEndpointTopOffset(targetEndpoints, graphOffsetY, edge?.to.stepId),
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
[graphPosition, targetEndpoints, edge?.to.stepId, targetBlockCoordinates?.y]
|
||||
[
|
||||
targetBlockCoordinates?.x,
|
||||
targetBlockCoordinates?.y,
|
||||
edge?.to.stepId,
|
||||
targetEndpoints,
|
||||
]
|
||||
)
|
||||
|
||||
const path = useMemo(() => {
|
||||
|
@ -24,6 +24,8 @@ export const Edges = ({
|
||||
pos="absolute"
|
||||
left="0"
|
||||
top="0"
|
||||
pointerEvents="none"
|
||||
shape-rendering="geometricPrecision"
|
||||
>
|
||||
<DrawingEdge />
|
||||
{edges.map((edge) => (
|
||||
|
@ -9,6 +9,7 @@ import { headerHeight } from 'components/shared/TypebotHeader/TypebotHeader'
|
||||
import { Block, DraggableStepType, PublicTypebot, Typebot } from 'models'
|
||||
import { generate } from 'short-uuid'
|
||||
import { AnswersCount } from 'services/analytics'
|
||||
import { useDebounce } from 'use-debounce'
|
||||
|
||||
export const Graph = ({
|
||||
typebot,
|
||||
@ -30,7 +31,9 @@ export const Graph = ({
|
||||
setGraphPosition,
|
||||
setOpenedStepId,
|
||||
updateBlockCoordinates,
|
||||
setGraphOffsetY,
|
||||
} = useGraph()
|
||||
const [debouncedGraphPosition] = useDebounce(graphPosition, 200)
|
||||
const transform = useMemo(
|
||||
() =>
|
||||
`translate(${graphPosition.x}px, ${graphPosition.y}px) scale(${graphPosition.scale})`,
|
||||
@ -42,8 +45,18 @@ export const Graph = ({
|
||||
editorContainerRef.current = document.getElementById(
|
||||
'editor-container'
|
||||
) as HTMLDivElement
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [])
|
||||
|
||||
useEffect(() => {
|
||||
if (!graphContainerRef.current) return
|
||||
setGraphOffsetY(
|
||||
graphContainerRef.current.getBoundingClientRect().top +
|
||||
debouncedGraphPosition.y
|
||||
)
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [debouncedGraphPosition])
|
||||
|
||||
const handleMouseWheel = (e: WheelEvent) => {
|
||||
e.preventDefault()
|
||||
const isPinchingTrackpad = e.ctrlKey
|
||||
@ -112,15 +125,19 @@ export const Graph = ({
|
||||
ref={graphContainerRef}
|
||||
onMouseDown={handleMouseDown}
|
||||
onMouseMove={handleMouseMove}
|
||||
position="relative"
|
||||
{...props}
|
||||
>
|
||||
<Flex
|
||||
flex="1"
|
||||
boxSize={'200px'}
|
||||
maxW={'200px'}
|
||||
w="full"
|
||||
h="full"
|
||||
position="absolute"
|
||||
style={{
|
||||
transform,
|
||||
}}
|
||||
willChange="transform"
|
||||
transformOrigin="0px 0px 0px"
|
||||
>
|
||||
<Edges
|
||||
edges={typebot?.edges ?? []}
|
||||
|
Reference in New Issue
Block a user