Skip to content

Feat: Use memo to wrap canvas nodes to improve fluency #3221 #7929

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
May 29, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion web/src/components/llm-select/llm-label.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { getLLMIconName, getLlmNameAndFIdByLlmId } from '@/utils/llm-util';
import { memo } from 'react';
import { LlmIcon } from '../svg-icon';

interface IProps {
Expand All @@ -24,4 +25,4 @@ const LLMLabel = ({ value }: IProps) => {
);
};

export default LLMLabel;
export default memo(LLMLabel);
8 changes: 5 additions & 3 deletions web/src/components/llm-select/next.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { LlmModelType } from '@/constants/knowledge';
import { useComposeLlmOptionsByModelTypes } from '@/hooks/llm-hooks';
import * as SelectPrimitive from '@radix-ui/react-select';
import { forwardRef, useState } from 'react';
import { forwardRef, memo, useState } from 'react';
import { LlmSettingFieldItems } from '../llm-setting-items/next';
import { Popover, PopoverContent, PopoverTrigger } from '../ui/popover';
import { Select, SelectTrigger, SelectValue } from '../ui/select';
Expand All @@ -14,7 +14,7 @@ interface IProps {
disabled?: boolean;
}

export const NextLLMSelect = forwardRef<
const NextInnerLLMSelect = forwardRef<
React.ElementRef<typeof SelectPrimitive.Trigger>,
IProps
>(({ value, disabled }, ref) => {
Expand Down Expand Up @@ -52,4 +52,6 @@ export const NextLLMSelect = forwardRef<
);
});

NextLLMSelect.displayName = 'LLMSelect';
NextInnerLLMSelect.displayName = 'LLMSelect';

export const NextLLMSelect = memo(NextInnerLLMSelect);
6 changes: 4 additions & 2 deletions web/src/pages/agent/agent-sidebar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import {
SidebarHeader,
SidebarMenu,
} from '@/components/ui/sidebar';
import { useMemo } from 'react';
import { memo, useMemo } from 'react';
import {
AgentOperatorList,
Operator,
Expand Down Expand Up @@ -77,7 +77,7 @@ function OperatorCollapsible({
);
}

export function AgentSidebar() {
function InnerAgentSidebar() {
const agentOperatorList = useMemo(() => {
return componentMenuList.filter((x) =>
AgentOperatorList.some((y) => y === x.name),
Expand Down Expand Up @@ -108,3 +108,5 @@ export function AgentSidebar() {
</Sidebar>
);
}

export const AgentSidebar = memo(InnerAgentSidebar);
4 changes: 2 additions & 2 deletions web/src/pages/agent/canvas/node/begin-node.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import { RightHandleStyle } from './handle-icon';
import styles from './index.less';

// TODO: do not allow other nodes to connect to this node
function Node({ selected, data }: NodeProps<IBeginNode>) {
function InnerBeginNode({ selected, data }: NodeProps<IBeginNode>) {
const { t } = useTranslation();
const query: BeginQuery[] = get(data, 'form.query', []);
const { theme } = useTheme();
Expand Down Expand Up @@ -72,4 +72,4 @@ function Node({ selected, data }: NodeProps<IBeginNode>) {
);
}

export const BeginNode = memo(Node);
export const BeginNode = memo(InnerBeginNode);
4 changes: 2 additions & 2 deletions web/src/pages/agent/canvas/node/categorize-handle.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Handle, Position } from '@xyflow/react';

import React from 'react';
import React, { memo } from 'react';
import styles from './index.less';

const DEFAULT_HANDLE_STYLE = {
Expand Down Expand Up @@ -37,4 +37,4 @@ const CategorizeHandle = ({ top, right, id, children }: IProps) => {
);
};

export default CategorizeHandle;
export default memo(CategorizeHandle);
5 changes: 4 additions & 1 deletion web/src/pages/agent/canvas/node/categorize-node.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,13 @@ import { Handle, NodeProps, Position } from '@xyflow/react';
import { Flex } from 'antd';
import classNames from 'classnames';
import { get } from 'lodash';
import { memo } from 'react';
import { RightHandleStyle } from './handle-icon';
import { useBuildCategorizeHandlePositions } from './hooks';
import styles from './index.less';
import NodeHeader from './node-header';

export function CategorizeNode({
export function InnerCategorizeNode({
id,
data,
selected,
Expand Down Expand Up @@ -66,3 +67,5 @@ export function CategorizeNode({
</section>
);
}

export const CategorizeNode = memo(InnerCategorizeNode);
6 changes: 4 additions & 2 deletions web/src/pages/agent/canvas/node/email-node.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@ import { IEmailNode } from '@/interfaces/database/flow';
import { Handle, NodeProps, Position } from '@xyflow/react';
import { Flex } from 'antd';
import classNames from 'classnames';
import { useState } from 'react';
import { memo, useState } from 'react';
import { LeftHandleStyle, RightHandleStyle } from './handle-icon';
import styles from './index.less';
import NodeHeader from './node-header';

export function EmailNode({
export function InnerEmailNode({
id,
data,
isConnectable = true,
Expand Down Expand Up @@ -76,3 +76,5 @@ export function EmailNode({
</section>
);
}

export const EmailNode = memo(InnerEmailNode);
5 changes: 4 additions & 1 deletion web/src/pages/agent/canvas/node/generate-node.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,12 @@ import { IGenerateNode } from '@/interfaces/database/flow';
import { Handle, NodeProps, Position } from '@xyflow/react';
import classNames from 'classnames';
import { get } from 'lodash';
import { memo } from 'react';
import { LeftHandleStyle, RightHandleStyle } from './handle-icon';
import styles from './index.less';
import NodeHeader from './node-header';

export function GenerateNode({
export function InnerGenerateNode({
id,
data,
isConnectable = true,
Expand Down Expand Up @@ -55,3 +56,5 @@ export function GenerateNode({
</section>
);
}

export const GenerateNode = memo(InnerGenerateNode);
5 changes: 4 additions & 1 deletion web/src/pages/agent/canvas/node/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@ import { useTheme } from '@/components/theme-provider';
import { IRagNode } from '@/interfaces/database/flow';
import { Handle, NodeProps, Position } from '@xyflow/react';
import classNames from 'classnames';
import { memo } from 'react';
import { LeftHandleStyle, RightHandleStyle } from './handle-icon';
import styles from './index.less';
import NodeHeader from './node-header';

export function RagNode({
function InnerRagNode({
id,
data,
isConnectable = true,
Expand Down Expand Up @@ -43,3 +44,5 @@ export function RagNode({
</section>
);
}

export const RagNode = memo(InnerRagNode);
5 changes: 4 additions & 1 deletion web/src/pages/agent/canvas/node/invoke-node.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,13 @@ import { Handle, NodeProps, Position } from '@xyflow/react';
import { Flex } from 'antd';
import classNames from 'classnames';
import { get } from 'lodash';
import { memo } from 'react';
import { useTranslation } from 'react-i18next';
import { LeftHandleStyle, RightHandleStyle } from './handle-icon';
import styles from './index.less';
import NodeHeader from './node-header';

export function InvokeNode({
function InnerInvokeNode({
id,
data,
isConnectable = true,
Expand Down Expand Up @@ -57,3 +58,5 @@ export function InvokeNode({
</section>
);
}

export const InvokeNode = memo(InnerInvokeNode);
9 changes: 7 additions & 2 deletions web/src/pages/agent/canvas/node/iteration-node.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
import { cn } from '@/lib/utils';
import { Handle, NodeProps, NodeResizeControl, Position } from '@xyflow/react';
import { ListRestart } from 'lucide-react';
import { memo } from 'react';
import { LeftHandleStyle, RightHandleStyle } from './handle-icon';
import styles from './index.less';
import NodeHeader from './node-header';
Expand Down Expand Up @@ -43,7 +44,7 @@ const controlStyle = {
cursor: 'nwse-resize',
};

export function IterationNode({
export function InnerIterationNode({
id,
data,
isConnectable = true,
Expand Down Expand Up @@ -98,7 +99,7 @@ export function IterationNode({
);
}

export function IterationStartNode({
function InnerIterationStartNode({
isConnectable = true,
selected,
}: NodeProps<IIterationStartNode>) {
Expand All @@ -125,3 +126,7 @@ export function IterationStartNode({
</section>
);
}

export const IterationStartNode = memo(InnerIterationStartNode);

export const IterationNode = memo(InnerIterationNode);
5 changes: 4 additions & 1 deletion web/src/pages/agent/canvas/node/keyword-node.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,12 @@ import { IKeywordNode } from '@/interfaces/database/flow';
import { Handle, NodeProps, Position } from '@xyflow/react';
import classNames from 'classnames';
import { get } from 'lodash';
import { memo } from 'react';
import { LeftHandleStyle, RightHandleStyle } from './handle-icon';
import styles from './index.less';
import NodeHeader from './node-header';

export function KeywordNode({
export function InnerKeywordNode({
id,
data,
isConnectable = true,
Expand Down Expand Up @@ -55,3 +56,5 @@ export function KeywordNode({
</section>
);
}

export const KeywordNode = memo(InnerKeywordNode);
5 changes: 4 additions & 1 deletion web/src/pages/agent/canvas/node/logic-node.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@ import { useTheme } from '@/components/theme-provider';
import { ILogicNode } from '@/interfaces/database/flow';
import { Handle, NodeProps, Position } from '@xyflow/react';
import classNames from 'classnames';
import { memo } from 'react';
import { LeftHandleStyle, RightHandleStyle } from './handle-icon';
import styles from './index.less';
import NodeHeader from './node-header';

export function LogicNode({
export function InnerLogicNode({
id,
data,
isConnectable = true,
Expand Down Expand Up @@ -43,3 +44,5 @@ export function LogicNode({
</section>
);
}

export const LogicNode = memo(InnerLogicNode);
5 changes: 4 additions & 1 deletion web/src/pages/agent/canvas/node/message-node.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,12 @@ import { Handle, NodeProps, Position } from '@xyflow/react';
import { Flex } from 'antd';
import classNames from 'classnames';
import { get } from 'lodash';
import { memo } from 'react';
import { LeftHandleStyle, RightHandleStyle } from './handle-icon';
import styles from './index.less';
import NodeHeader from './node-header';

export function MessageNode({
function InnerMessageNode({
id,
data,
isConnectable = true,
Expand Down Expand Up @@ -63,3 +64,5 @@ export function MessageNode({
</section>
);
}

export const MessageNode = memo(InnerMessageNode);
5 changes: 4 additions & 1 deletion web/src/pages/agent/canvas/node/node-header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { needsSingleStepDebugging } from '../../utils';
import NodeDropdown from './dropdown';
import { NextNodePopover } from './popover';

import { memo } from 'react';
import { RunTooltip } from '../../flow-tooltip';
interface IProps {
id: string;
Expand Down Expand Up @@ -37,7 +38,7 @@ export function RunStatus({ id, name, label }: IProps) {
);
}

const NodeHeader = ({
const InnerNodeHeader = ({
label,
id,
name,
Expand Down Expand Up @@ -70,4 +71,6 @@ const NodeHeader = ({
);
};

const NodeHeader = memo(InnerNodeHeader);

export default NodeHeader;
5 changes: 4 additions & 1 deletion web/src/pages/agent/canvas/node/relevant-node.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,12 @@ import { RightHandleStyle } from './handle-icon';
import { useTheme } from '@/components/theme-provider';
import { IRelevantNode } from '@/interfaces/database/flow';
import { get } from 'lodash';
import { memo } from 'react';
import { useReplaceIdWithName } from '../../hooks';
import styles from './index.less';
import NodeHeader from './node-header';

export function RelevantNode({ id, data, selected }: NodeProps<IRelevantNode>) {
function InnerRelevantNode({ id, data, selected }: NodeProps<IRelevantNode>) {
const yes = get(data, 'form.yes');
const no = get(data, 'form.no');
const replaceIdWithName = useReplaceIdWithName();
Expand Down Expand Up @@ -68,3 +69,5 @@ export function RelevantNode({ id, data, selected }: NodeProps<IRelevantNode>) {
</section>
);
}

export const RelevantNode = memo(InnerRelevantNode);
6 changes: 4 additions & 2 deletions web/src/pages/agent/canvas/node/retrieval-node.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@ import { Handle, NodeProps, Position } from '@xyflow/react';
import { Avatar, Flex } from 'antd';
import classNames from 'classnames';
import { get } from 'lodash';
import { useMemo } from 'react';
import { memo, useMemo } from 'react';
import { LeftHandleStyle, RightHandleStyle } from './handle-icon';
import styles from './index.less';
import NodeHeader from './node-header';

export function RetrievalNode({
function InnerRetrievalNode({
id,
data,
isConnectable = true,
Expand Down Expand Up @@ -86,3 +86,5 @@ export function RetrievalNode({
</section>
);
}

export const RetrievalNode = memo(InnerRetrievalNode);
5 changes: 4 additions & 1 deletion web/src/pages/agent/canvas/node/rewrite-node.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,12 @@ import { IRewriteNode } from '@/interfaces/database/flow';
import { Handle, NodeProps, Position } from '@xyflow/react';
import classNames from 'classnames';
import { get } from 'lodash';
import { memo } from 'react';
import { LeftHandleStyle, RightHandleStyle } from './handle-icon';
import styles from './index.less';
import NodeHeader from './node-header';

export function RewriteNode({
function InnerRewriteNode({
id,
data,
isConnectable = true,
Expand Down Expand Up @@ -55,3 +56,5 @@ export function RewriteNode({
</section>
);
}

export const RewriteNode = memo(InnerRewriteNode);
5 changes: 4 additions & 1 deletion web/src/pages/agent/canvas/node/switch-node.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { ISwitchCondition, ISwitchNode } from '@/interfaces/database/flow';
import { Handle, NodeProps, Position } from '@xyflow/react';
import { Divider, Flex } from 'antd';
import classNames from 'classnames';
import { memo } from 'react';
import { useGetComponentLabelByValue } from '../../hooks/use-get-begin-query';
import { RightHandleStyle } from './handle-icon';
import { useBuildSwitchHandlePositions } from './hooks';
Expand Down Expand Up @@ -54,7 +55,7 @@ const ConditionBlock = ({
);
};

export function SwitchNode({ id, data, selected }: NodeProps<ISwitchNode>) {
function InnerSwitchNode({ id, data, selected }: NodeProps<ISwitchNode>) {
const { positions } = useBuildSwitchHandlePositions({ data, id });
const { theme } = useTheme();
return (
Expand Down Expand Up @@ -112,3 +113,5 @@ export function SwitchNode({ id, data, selected }: NodeProps<ISwitchNode>) {
</section>
);
}

export const SwitchNode = memo(InnerSwitchNode);
Loading