diff --git a/invokeai/frontend/web/src/features/nodes/components/AddNodeMenu.tsx b/invokeai/frontend/web/src/features/nodes/components/AddNodeMenu.tsx
index 713ab160e7..5acd0c0530 100644
--- a/invokeai/frontend/web/src/features/nodes/components/AddNodeMenu.tsx
+++ b/invokeai/frontend/web/src/features/nodes/components/AddNodeMenu.tsx
@@ -1,7 +1,7 @@
import { v4 as uuidv4 } from 'uuid';
import 'reactflow/dist/style.css';
-import { useCallback } from 'react';
+import { memo, useCallback } from 'react';
import {
Tooltip,
Menu,
@@ -21,7 +21,7 @@ import { makeToast } from 'features/system/hooks/useToastWatcher';
import { IAIIconButton } from 'exports';
import { AnyInvocationType } from 'services/events/types';
-export const AddNodeMenu = () => {
+const AddNodeMenu = () => {
const dispatch = useAppDispatch();
const invocationTemplates = useAppSelector(
@@ -67,3 +67,5 @@ export const AddNodeMenu = () => {
);
};
+
+export default memo(AddNodeMenu);
diff --git a/invokeai/frontend/web/src/features/nodes/components/FieldTypeLegend.tsx b/invokeai/frontend/web/src/features/nodes/components/FieldTypeLegend.tsx
index a420376016..4f46b03b7a 100644
--- a/invokeai/frontend/web/src/features/nodes/components/FieldTypeLegend.tsx
+++ b/invokeai/frontend/web/src/features/nodes/components/FieldTypeLegend.tsx
@@ -2,8 +2,9 @@ import 'reactflow/dist/style.css';
import { Tooltip, Badge, HStack } from '@chakra-ui/react';
import { map } from 'lodash';
import { FIELDS } from '../types/constants';
+import { memo } from 'react';
-export const FieldTypeLegend = () => {
+const FieldTypeLegend = () => {
return (
{map(FIELDS, ({ title, description, color }, key) => (
@@ -16,3 +17,5 @@ export const FieldTypeLegend = () => {
);
};
+
+export default memo(FieldTypeLegend);
diff --git a/invokeai/frontend/web/src/features/nodes/components/Flow.tsx b/invokeai/frontend/web/src/features/nodes/components/Flow.tsx
index fd89244bc8..173458d285 100644
--- a/invokeai/frontend/web/src/features/nodes/components/Flow.tsx
+++ b/invokeai/frontend/web/src/features/nodes/components/Flow.tsx
@@ -1,15 +1,12 @@
import {
Background,
- Controls,
MiniMap,
OnConnect,
OnEdgesChange,
OnNodesChange,
ReactFlow,
- ConnectionLineType,
OnConnectStart,
OnConnectEnd,
- Panel,
} from 'reactflow';
import { useAppDispatch, useAppSelector } from 'app/storeHooks';
import { RootState } from 'app/store';
@@ -20,16 +17,8 @@ import {
edgesChanged,
nodesChanged,
} from '../store/nodesSlice';
-import { useCallback, useState } from 'react';
+import { useCallback } from 'react';
import { InvocationComponent } from './InvocationComponent';
-import { AddNodeMenu } from './AddNodeMenu';
-import { FieldTypeLegend } from './FieldTypeLegend';
-import { Button } from '@chakra-ui/react';
-import { nodesGraphBuilt } from 'services/thunks/session';
-import { IAIIconButton } from 'exports';
-import { InfoIcon } from '@chakra-ui/icons';
-import { ViewportControls } from './ViewportControls';
-import NodeGraphOverlay from './NodeGraphOverlay';
import TopLeftPanel from './panels/TopLeftPanel';
import TopRightPanel from './panels/TopRightPanel';
import TopCenterPanel from './panels/TopCenterPanel';
diff --git a/invokeai/frontend/web/src/features/nodes/components/IAINode/IAINodeHeader.tsx b/invokeai/frontend/web/src/features/nodes/components/IAINode/IAINodeHeader.tsx
index 4a5ded7734..2a61d4cc2b 100644
--- a/invokeai/frontend/web/src/features/nodes/components/IAINode/IAINodeHeader.tsx
+++ b/invokeai/frontend/web/src/features/nodes/components/IAINode/IAINodeHeader.tsx
@@ -1,6 +1,6 @@
import { Flex, Heading, Tooltip, Icon } from '@chakra-ui/react';
import { InvocationTemplate } from 'features/nodes/types/types';
-import { MutableRefObject } from 'react';
+import { memo, MutableRefObject } from 'react';
import { FaInfoCircle } from 'react-icons/fa';
interface IAINodeHeaderProps {
@@ -8,7 +8,7 @@ interface IAINodeHeaderProps {
template: InvocationTemplate;
}
-export default function IAINodeHeader(props: IAINodeHeaderProps) {
+const IAINodeHeader = (props: IAINodeHeaderProps) => {
const { nodeId, template } = props;
return (
);
-}
+};
+
+export default memo(IAINodeHeader);
diff --git a/invokeai/frontend/web/src/features/nodes/components/IAINode/IAINodeInputs.tsx b/invokeai/frontend/web/src/features/nodes/components/IAINode/IAINodeInputs.tsx
index 6422ab4555..61cdf67803 100644
--- a/invokeai/frontend/web/src/features/nodes/components/IAINode/IAINodeInputs.tsx
+++ b/invokeai/frontend/web/src/features/nodes/components/IAINode/IAINodeInputs.tsx
@@ -19,7 +19,7 @@ import {
} from '@chakra-ui/react';
import FieldHandle from '../FieldHandle';
import { useIsValidConnection } from 'features/nodes/hooks/useIsValidConnection';
-import { InputFieldComponent } from '../InputFieldComponent';
+import InputFieldComponent from '../InputFieldComponent';
import { FaInfoCircle } from 'react-icons/fa';
import { HANDLE_TOOLTIP_OPEN_DELAY } from 'features/nodes/types/constants';
diff --git a/invokeai/frontend/web/src/features/nodes/components/IAINode/IAINodeResizer.tsx b/invokeai/frontend/web/src/features/nodes/components/IAINode/IAINodeResizer.tsx
index 2ef82f6a9b..0fa13c82b6 100644
--- a/invokeai/frontend/web/src/features/nodes/components/IAINode/IAINodeResizer.tsx
+++ b/invokeai/frontend/web/src/features/nodes/components/IAINode/IAINodeResizer.tsx
@@ -1,6 +1,7 @@
+import { memo } from 'react';
import { NodeResizeControl, NodeResizerProps } from 'reactflow';
-export default function IAINodeResizer(props: NodeResizerProps) {
+const IAINodeResizer = (props: NodeResizerProps) => {
const { ...rest } = props;
return (
);
-}
+};
+
+export default memo(IAINodeResizer);
diff --git a/invokeai/frontend/web/src/features/nodes/components/InputFieldComponent.tsx b/invokeai/frontend/web/src/features/nodes/components/InputFieldComponent.tsx
index 80a3241e13..21e4b9fcfb 100644
--- a/invokeai/frontend/web/src/features/nodes/components/InputFieldComponent.tsx
+++ b/invokeai/frontend/web/src/features/nodes/components/InputFieldComponent.tsx
@@ -1,13 +1,14 @@
import { Box } from '@chakra-ui/react';
+import { memo } from 'react';
import { InputFieldTemplate, InputFieldValue } from '../types/types';
-import { ArrayInputFieldComponent } from './fields/ArrayInputFieldComponent';
-import { BooleanInputFieldComponent } from './fields/BooleanInputFieldComponent';
-import { EnumInputFieldComponent } from './fields/EnumInputFieldComponent';
-import { ImageInputFieldComponent } from './fields/ImageInputFieldComponent';
-import { LatentsInputFieldComponent } from './fields/LatentsInputFieldComponent';
-import { ModelInputFieldComponent } from './fields/ModelInputFieldComponent';
-import { NumberInputFieldComponent } from './fields/NumberInputFieldComponent';
-import { StringInputFieldComponent } from './fields/StringInputFieldComponent';
+import ArrayInputFieldComponent from './fields/ArrayInputFieldComponent';
+import BooleanInputFieldComponent from './fields/BooleanInputFieldComponent';
+import EnumInputFieldComponent from './fields/EnumInputFieldComponent';
+import ImageInputFieldComponent from './fields/ImageInputFieldComponent';
+import LatentsInputFieldComponent from './fields/LatentsInputFieldComponent';
+import ModelInputFieldComponent from './fields/ModelInputFieldComponent';
+import NumberInputFieldComponent from './fields/NumberInputFieldComponent';
+import StringInputFieldComponent from './fields/StringInputFieldComponent';
type InputFieldComponentProps = {
nodeId: string;
@@ -16,7 +17,7 @@ type InputFieldComponentProps = {
};
// build an individual input element based on the schema
-export const InputFieldComponent = (props: InputFieldComponentProps) => {
+const InputFieldComponent = (props: InputFieldComponentProps) => {
const { nodeId, field, template } = props;
const { type, value } = field;
@@ -105,3 +106,5 @@ export const InputFieldComponent = (props: InputFieldComponentProps) => {
return Unknown field type: {type};
};
+
+export default memo(InputFieldComponent);
diff --git a/invokeai/frontend/web/src/features/nodes/components/InvocationComponent.tsx b/invokeai/frontend/web/src/features/nodes/components/InvocationComponent.tsx
index f85208c936..c0ddf1c3b3 100644
--- a/invokeai/frontend/web/src/features/nodes/components/InvocationComponent.tsx
+++ b/invokeai/frontend/web/src/features/nodes/components/InvocationComponent.tsx
@@ -1,14 +1,12 @@
-import { NodeProps, NodeResizeControl } from 'reactflow';
+import { NodeProps } from 'reactflow';
import { Box, Flex, Icon, useToken } from '@chakra-ui/react';
import { FaExclamationCircle } from 'react-icons/fa';
import { InvocationTemplate, InvocationValue } from '../types/types';
-import { memo, PropsWithChildren, useMemo, useRef } from 'react';
-import { useGetInvocationTemplate } from '../hooks/useInvocationTemplate';
+import { memo, PropsWithChildren, useMemo } from 'react';
import IAINodeOutputs from './IAINode/IAINodeOutputs';
import IAINodeInputs from './IAINode/IAINodeInputs';
import IAINodeHeader from './IAINode/IAINodeHeader';
-import { IoResize } from 'react-icons/io5';
import IAINodeResizer from './IAINode/IAINodeResizer';
import { RootState } from 'app/store';
import { AnyInvocationType } from 'services/events/types';
diff --git a/invokeai/frontend/web/src/features/nodes/components/NodeEditor.tsx b/invokeai/frontend/web/src/features/nodes/components/NodeEditor.tsx
index 5739c3f60e..05f8c2a893 100644
--- a/invokeai/frontend/web/src/features/nodes/components/NodeEditor.tsx
+++ b/invokeai/frontend/web/src/features/nodes/components/NodeEditor.tsx
@@ -3,6 +3,7 @@ import { Box } from '@chakra-ui/react';
import { ReactFlowProvider } from 'reactflow';
import { Flow } from './Flow';
+import { memo } from 'react';
const NodeEditor = () => {
return (
@@ -22,4 +23,4 @@ const NodeEditor = () => {
);
};
-export default NodeEditor;
+export default memo(NodeEditor);
diff --git a/invokeai/frontend/web/src/features/nodes/components/NodeGraphOverlay.tsx b/invokeai/frontend/web/src/features/nodes/components/NodeGraphOverlay.tsx
index 80bc45bc5b..88a125e542 100644
--- a/invokeai/frontend/web/src/features/nodes/components/NodeGraphOverlay.tsx
+++ b/invokeai/frontend/web/src/features/nodes/components/NodeGraphOverlay.tsx
@@ -1,9 +1,10 @@
import { Box } from '@chakra-ui/react';
import { RootState } from 'app/store';
import { useAppSelector } from 'app/storeHooks';
+import { memo } from 'react';
import { buildNodesGraph } from '../util/nodesGraphBuilder/buildNodesGraph';
-export default function NodeGraphOverlay() {
+const NodeGraphOverlay = () => {
const state = useAppSelector((state: RootState) => state);
const graph = buildNodesGraph(state);
@@ -14,7 +15,6 @@ export default function NodeGraphOverlay() {
position="absolute"
top={10}
right={2}
- userSelect="none"
opacity={0.7}
background="base.800"
p={2}
@@ -25,4 +25,6 @@ export default function NodeGraphOverlay() {
{JSON.stringify(graph, null, 2)}
);
-}
+};
+
+export default memo(NodeGraphOverlay);
diff --git a/invokeai/frontend/web/src/features/nodes/components/ViewportControls.tsx b/invokeai/frontend/web/src/features/nodes/components/ViewportControls.tsx
index c43c6c77de..249e8d4c78 100644
--- a/invokeai/frontend/web/src/features/nodes/components/ViewportControls.tsx
+++ b/invokeai/frontend/web/src/features/nodes/components/ViewportControls.tsx
@@ -1,12 +1,12 @@
import { ButtonGroup } from '@chakra-ui/react';
import { useAppDispatch, useAppSelector } from 'app/storeHooks';
import { IAIIconButton } from 'exports';
-import { useCallback } from 'react';
+import { memo, useCallback } from 'react';
import { FaCode, FaExpand, FaMinus, FaPlus } from 'react-icons/fa';
import { useReactFlow } from 'reactflow';
import { shouldShowGraphOverlayChanged } from '../store/nodesSlice';
-export const ViewportControls = () => {
+const ViewportControls = () => {
const { zoomIn, zoomOut, fitView } = useReactFlow();
const dispatch = useAppDispatch();
const shouldShowGraphOverlay = useAppSelector(
@@ -55,3 +55,5 @@ export const ViewportControls = () => {
);
};
+
+export default memo(ViewportControls);
diff --git a/invokeai/frontend/web/src/features/nodes/components/fields/ArrayInputFieldComponent.tsx b/invokeai/frontend/web/src/features/nodes/components/fields/ArrayInputFieldComponent.tsx
index 1dd4b1d8af..6f437dfcd8 100644
--- a/invokeai/frontend/web/src/features/nodes/components/fields/ArrayInputFieldComponent.tsx
+++ b/invokeai/frontend/web/src/features/nodes/components/fields/ArrayInputFieldComponent.tsx
@@ -2,13 +2,16 @@ import {
ArrayInputFieldTemplate,
ArrayInputFieldValue,
} from 'features/nodes/types/types';
-import { FaImage, FaList } from 'react-icons/fa';
+import { memo } from 'react';
+import { FaList } from 'react-icons/fa';
import { FieldComponentProps } from './types';
-export const ArrayInputFieldComponent = (
+const ArrayInputFieldComponent = (
props: FieldComponentProps
) => {
const { nodeId, field } = props;
return ;
};
+
+export default memo(ArrayInputFieldComponent);
diff --git a/invokeai/frontend/web/src/features/nodes/components/fields/BooleanInputFieldComponent.tsx b/invokeai/frontend/web/src/features/nodes/components/fields/BooleanInputFieldComponent.tsx
index 948aa2bb0a..ceb2364e46 100644
--- a/invokeai/frontend/web/src/features/nodes/components/fields/BooleanInputFieldComponent.tsx
+++ b/invokeai/frontend/web/src/features/nodes/components/fields/BooleanInputFieldComponent.tsx
@@ -5,10 +5,10 @@ import {
BooleanInputFieldTemplate,
BooleanInputFieldValue,
} from 'features/nodes/types/types';
-import { ChangeEvent } from 'react';
+import { ChangeEvent, memo } from 'react';
import { FieldComponentProps } from './types';
-export const BooleanInputFieldComponent = (
+const BooleanInputFieldComponent = (
props: FieldComponentProps
) => {
const { nodeId, field } = props;
@@ -29,3 +29,5 @@ export const BooleanInputFieldComponent = (
);
};
+
+export default memo(BooleanInputFieldComponent);
diff --git a/invokeai/frontend/web/src/features/nodes/components/fields/EnumInputFieldComponent.tsx b/invokeai/frontend/web/src/features/nodes/components/fields/EnumInputFieldComponent.tsx
index 87425a28f2..15602e7cad 100644
--- a/invokeai/frontend/web/src/features/nodes/components/fields/EnumInputFieldComponent.tsx
+++ b/invokeai/frontend/web/src/features/nodes/components/fields/EnumInputFieldComponent.tsx
@@ -5,10 +5,10 @@ import {
EnumInputFieldTemplate,
EnumInputFieldValue,
} from 'features/nodes/types/types';
-import { ChangeEvent } from 'react';
+import { ChangeEvent, memo } from 'react';
import { FieldComponentProps } from './types';
-export const EnumInputFieldComponent = (
+const EnumInputFieldComponent = (
props: FieldComponentProps
) => {
const { nodeId, field, template } = props;
@@ -33,3 +33,5 @@ export const EnumInputFieldComponent = (
);
};
+
+export default memo(EnumInputFieldComponent);
diff --git a/invokeai/frontend/web/src/features/nodes/components/fields/ImageInputFieldComponent.tsx b/invokeai/frontend/web/src/features/nodes/components/fields/ImageInputFieldComponent.tsx
index d07dfa4c6c..1dc0296139 100644
--- a/invokeai/frontend/web/src/features/nodes/components/fields/ImageInputFieldComponent.tsx
+++ b/invokeai/frontend/web/src/features/nodes/components/fields/ImageInputFieldComponent.tsx
@@ -9,12 +9,12 @@ import {
ImageInputFieldTemplate,
ImageInputFieldValue,
} from 'features/nodes/types/types';
-import { DragEvent, useCallback, useState } from 'react';
+import { DragEvent, memo, useCallback, useState } from 'react';
import { FaImage } from 'react-icons/fa';
import { ImageType } from 'services/api';
import { FieldComponentProps } from './types';
-export const ImageInputFieldComponent = (
+const ImageInputFieldComponent = (
props: FieldComponentProps
) => {
const { nodeId, field } = props;
@@ -62,3 +62,5 @@ export const ImageInputFieldComponent = (
);
};
+
+export default memo(ImageInputFieldComponent);
diff --git a/invokeai/frontend/web/src/features/nodes/components/fields/LatentsInputFieldComponent.tsx b/invokeai/frontend/web/src/features/nodes/components/fields/LatentsInputFieldComponent.tsx
index 1edf07e014..2de0a07eb5 100644
--- a/invokeai/frontend/web/src/features/nodes/components/fields/LatentsInputFieldComponent.tsx
+++ b/invokeai/frontend/web/src/features/nodes/components/fields/LatentsInputFieldComponent.tsx
@@ -2,12 +2,15 @@ import {
LatentsInputFieldTemplate,
LatentsInputFieldValue,
} from 'features/nodes/types/types';
+import { memo } from 'react';
import { FieldComponentProps } from './types';
-export const LatentsInputFieldComponent = (
+const LatentsInputFieldComponent = (
props: FieldComponentProps
) => {
const { nodeId, field } = props;
return null;
};
+
+export default memo(LatentsInputFieldComponent);
diff --git a/invokeai/frontend/web/src/features/nodes/components/fields/ModelInputFieldComponent.tsx b/invokeai/frontend/web/src/features/nodes/components/fields/ModelInputFieldComponent.tsx
index b4f60acbd0..14f2816e1c 100644
--- a/invokeai/frontend/web/src/features/nodes/components/fields/ModelInputFieldComponent.tsx
+++ b/invokeai/frontend/web/src/features/nodes/components/fields/ModelInputFieldComponent.tsx
@@ -12,7 +12,7 @@ import {
selectModelsIds,
} from 'features/system/store/modelSlice';
import { isEqual, map } from 'lodash';
-import { ChangeEvent } from 'react';
+import { ChangeEvent, memo } from 'react';
import { FieldComponentProps } from './types';
const availableModelsSelector = createSelector(
@@ -28,7 +28,7 @@ const availableModelsSelector = createSelector(
}
);
-export const ModelInputFieldComponent = (
+const ModelInputFieldComponent = (
props: FieldComponentProps
) => {
const { nodeId, field } = props;
@@ -55,3 +55,5 @@ export const ModelInputFieldComponent = (
);
};
+
+export default memo(ModelInputFieldComponent);
diff --git a/invokeai/frontend/web/src/features/nodes/components/fields/NumberInputFieldComponent.tsx b/invokeai/frontend/web/src/features/nodes/components/fields/NumberInputFieldComponent.tsx
index 3ef54a8a5a..f3c563f4fa 100644
--- a/invokeai/frontend/web/src/features/nodes/components/fields/NumberInputFieldComponent.tsx
+++ b/invokeai/frontend/web/src/features/nodes/components/fields/NumberInputFieldComponent.tsx
@@ -13,9 +13,10 @@ import {
IntegerInputFieldTemplate,
IntegerInputFieldValue,
} from 'features/nodes/types/types';
+import { memo } from 'react';
import { FieldComponentProps } from './types';
-export const NumberInputFieldComponent = (
+const NumberInputFieldComponent = (
props: FieldComponentProps<
IntegerInputFieldValue | FloatInputFieldValue,
IntegerInputFieldTemplate | FloatInputFieldTemplate
@@ -39,3 +40,5 @@ export const NumberInputFieldComponent = (
);
};
+
+export default memo(NumberInputFieldComponent);
diff --git a/invokeai/frontend/web/src/features/nodes/components/fields/StringInputFieldComponent.tsx b/invokeai/frontend/web/src/features/nodes/components/fields/StringInputFieldComponent.tsx
index 54341df31a..f371e8e58d 100644
--- a/invokeai/frontend/web/src/features/nodes/components/fields/StringInputFieldComponent.tsx
+++ b/invokeai/frontend/web/src/features/nodes/components/fields/StringInputFieldComponent.tsx
@@ -5,10 +5,10 @@ import {
StringInputFieldTemplate,
StringInputFieldValue,
} from 'features/nodes/types/types';
-import { ChangeEvent } from 'react';
+import { ChangeEvent, memo } from 'react';
import { FieldComponentProps } from './types';
-export const StringInputFieldComponent = (
+const StringInputFieldComponent = (
props: FieldComponentProps
) => {
const { nodeId, field } = props;
@@ -27,3 +27,5 @@ export const StringInputFieldComponent = (
return ;
};
+
+export default memo(StringInputFieldComponent);
diff --git a/invokeai/frontend/web/src/features/nodes/components/panels/BottomLeftPanel.tsx.tsx b/invokeai/frontend/web/src/features/nodes/components/panels/BottomLeftPanel.tsx.tsx
index 7957acf271..fefad5f490 100644
--- a/invokeai/frontend/web/src/features/nodes/components/panels/BottomLeftPanel.tsx.tsx
+++ b/invokeai/frontend/web/src/features/nodes/components/panels/BottomLeftPanel.tsx.tsx
@@ -1,6 +1,6 @@
import { memo } from 'react';
import { Panel } from 'reactflow';
-import { ViewportControls } from '../ViewportControls';
+import ViewportControls from '../ViewportControls';
const BottomLeftPanel = () => (
diff --git a/invokeai/frontend/web/src/features/nodes/components/panels/TopLeftPanel.tsx b/invokeai/frontend/web/src/features/nodes/components/panels/TopLeftPanel.tsx
index 29e7cc1b14..2b89db000a 100644
--- a/invokeai/frontend/web/src/features/nodes/components/panels/TopLeftPanel.tsx
+++ b/invokeai/frontend/web/src/features/nodes/components/panels/TopLeftPanel.tsx
@@ -1,6 +1,6 @@
import { memo } from 'react';
import { Panel } from 'reactflow';
-import { AddNodeMenu } from '../AddNodeMenu';
+import AddNodeMenu from '../AddNodeMenu';
const TopLeftPanel = () => (
diff --git a/invokeai/frontend/web/src/features/nodes/components/panels/TopRightPanel.tsx b/invokeai/frontend/web/src/features/nodes/components/panels/TopRightPanel.tsx
index 094b7bb797..7e51e3e00e 100644
--- a/invokeai/frontend/web/src/features/nodes/components/panels/TopRightPanel.tsx
+++ b/invokeai/frontend/web/src/features/nodes/components/panels/TopRightPanel.tsx
@@ -2,7 +2,7 @@ import { RootState } from 'app/store';
import { useAppSelector } from 'app/storeHooks';
import { memo } from 'react';
import { Panel } from 'reactflow';
-import { FieldTypeLegend } from '../FieldTypeLegend';
+import FieldTypeLegend from '../FieldTypeLegend';
import NodeGraphOverlay from '../NodeGraphOverlay';
const TopRightPanel = () => {