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 = () => {