perf(ui): fix lag w/ region rendering

Needed to memoize these selectors
This commit is contained in:
psychedelicious 2024-06-19 00:06:06 +10:00
parent 418650fdf3
commit 5d81e7dd4d
3 changed files with 56 additions and 50 deletions

View File

@ -1,5 +1,5 @@
import { Menu, MenuItem, MenuList } from '@invoke-ai/ui-library'; import { Menu, MenuItem, MenuList } from '@invoke-ai/ui-library';
import { createAppSelector } from 'app/store/createMemoizedSelector'; import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks'; import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
import { CanvasEntityMenuButton } from 'features/controlLayers/components/common/CanvasEntityMenuButton'; import { CanvasEntityMenuButton } from 'features/controlLayers/components/common/CanvasEntityMenuButton';
import { import {
@ -11,7 +11,7 @@ import {
selectCanvasV2Slice, selectCanvasV2Slice,
} from 'features/controlLayers/store/canvasV2Slice'; } from 'features/controlLayers/store/canvasV2Slice';
import { selectCAOrThrow } from 'features/controlLayers/store/controlAdaptersReducers'; import { selectCAOrThrow } from 'features/controlLayers/store/controlAdaptersReducers';
import { memo, useCallback } from 'react'; import { memo, useCallback, useMemo } from 'react';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { import {
PiArrowDownBold, PiArrowDownBold,
@ -25,7 +25,12 @@ type Props = {
id: string; id: string;
}; };
const selectValidActions = createAppSelector([selectCanvasV2Slice, (canvasV2, id: string) => id], (canvasV2, id) => { export const CAActionsMenu = memo(({ id }: Props) => {
const { t } = useTranslation();
const dispatch = useAppDispatch();
const selectValidActions = useMemo(
() =>
createMemoizedSelector(selectCanvasV2Slice, (canvasV2) => {
const ca = selectCAOrThrow(canvasV2, id); const ca = selectCAOrThrow(canvasV2, id);
const caIndex = canvasV2.controlAdapters.indexOf(ca); const caIndex = canvasV2.controlAdapters.indexOf(ca);
const caCount = canvasV2.controlAdapters.length; const caCount = canvasV2.controlAdapters.length;
@ -35,12 +40,10 @@ const selectValidActions = createAppSelector([selectCanvasV2Slice, (canvasV2, id
canMoveToFront: caIndex < caCount - 1, canMoveToFront: caIndex < caCount - 1,
canMoveToBack: caIndex > 0, canMoveToBack: caIndex > 0,
}; };
}); }),
[id]
export const CAActionsMenu = memo(({ id }: Props) => { );
const { t } = useTranslation(); const validActions = useAppSelector(selectValidActions);
const dispatch = useAppDispatch();
const validActions = useAppSelector((s) => selectValidActions(s, id));
const onDelete = useCallback(() => { const onDelete = useCallback(() => {
dispatch(caDeleted({ id })); dispatch(caDeleted({ id }));
}, [dispatch, id]); }, [dispatch, id]);

View File

@ -1,5 +1,5 @@
import { Menu, MenuItem, MenuList } from '@invoke-ai/ui-library'; import { Menu, MenuItem, MenuList } from '@invoke-ai/ui-library';
import { createMemoizedAppSelector } from 'app/store/createMemoizedSelector'; import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks'; import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
import { CanvasEntityMenuButton } from 'features/controlLayers/components/common/CanvasEntityMenuButton'; import { CanvasEntityMenuButton } from 'features/controlLayers/components/common/CanvasEntityMenuButton';
import { import {
@ -11,7 +11,7 @@ import {
selectCanvasV2Slice, selectCanvasV2Slice,
} from 'features/controlLayers/store/canvasV2Slice'; } from 'features/controlLayers/store/canvasV2Slice';
import { selectLayerOrThrow } from 'features/controlLayers/store/layersReducers'; import { selectLayerOrThrow } from 'features/controlLayers/store/layersReducers';
import { memo, useCallback } from 'react'; import { memo, useCallback, useMemo } from 'react';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { import {
PiArrowDownBold, PiArrowDownBold,
@ -25,7 +25,12 @@ type Props = {
id: string; id: string;
}; };
const selectValidActions = createMemoizedAppSelector([selectCanvasV2Slice, (canvasV2, id: string) => id], (canvasV2, id) => { export const LayerActionsMenu = memo(({ id }: Props) => {
const { t } = useTranslation();
const dispatch = useAppDispatch();
const selectValidActions = useMemo(
() =>
createMemoizedSelector(selectCanvasV2Slice, (canvasV2) => {
const layer = selectLayerOrThrow(canvasV2, id); const layer = selectLayerOrThrow(canvasV2, id);
const layerIndex = canvasV2.layers.indexOf(layer); const layerIndex = canvasV2.layers.indexOf(layer);
const layerCount = canvasV2.layers.length; const layerCount = canvasV2.layers.length;
@ -35,12 +40,10 @@ const selectValidActions = createMemoizedAppSelector([selectCanvasV2Slice, (canv
canMoveToFront: layerIndex < layerCount - 1, canMoveToFront: layerIndex < layerCount - 1,
canMoveToBack: layerIndex > 0, canMoveToBack: layerIndex > 0,
}; };
}); }),
[id]
export const LayerActionsMenu = memo(({ id }: Props) => { );
const { t } = useTranslation(); const validActions = useAppSelector(selectValidActions);
const dispatch = useAppDispatch();
const validActions = useAppSelector((s) => selectValidActions(s, id));
const onDelete = useCallback(() => { const onDelete = useCallback(() => {
dispatch(layerDeleted({ id })); dispatch(layerDeleted({ id }));
}, [dispatch, id]); }, [dispatch, id]);

View File

@ -1,5 +1,5 @@
import { Menu, MenuDivider, MenuItem, MenuList } from '@invoke-ai/ui-library'; import { Menu, MenuDivider, MenuItem, MenuList } from '@invoke-ai/ui-library';
import { createMemoizedAppSelector } from 'app/store/createMemoizedSelector'; import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks'; import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
import { CanvasEntityMenuButton } from 'features/controlLayers/components/common/CanvasEntityMenuButton'; import { CanvasEntityMenuButton } from 'features/controlLayers/components/common/CanvasEntityMenuButton';
import { useAddIPAdapterToRGLayer } from 'features/controlLayers/hooks/addLayerHooks'; import { useAddIPAdapterToRGLayer } from 'features/controlLayers/hooks/addLayerHooks';
@ -15,7 +15,7 @@ import {
selectCanvasV2Slice, selectCanvasV2Slice,
} from 'features/controlLayers/store/canvasV2Slice'; } from 'features/controlLayers/store/canvasV2Slice';
import { selectRGOrThrow } from 'features/controlLayers/store/regionsReducers'; import { selectRGOrThrow } from 'features/controlLayers/store/regionsReducers';
import { memo, useCallback } from 'react'; import { memo, useCallback, useMemo } from 'react';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { import {
PiArrowCounterClockwiseBold, PiArrowCounterClockwiseBold,
@ -31,9 +31,13 @@ type Props = {
id: string; id: string;
}; };
const selectActionsValidity = createMemoizedAppSelector( export const RGActionsMenu = memo(({ id }: Props) => {
[selectCanvasV2Slice, (canvasV2, id: string) => id], const { t } = useTranslation();
(canvasV2, id) => { const dispatch = useAppDispatch();
const [onAddIPAdapter, isAddIPAdapterDisabled] = useAddIPAdapterToRGLayer(id);
const selectActionsValidity = useMemo(
() =>
createMemoizedSelector(selectCanvasV2Slice, (canvasV2) => {
const rg = selectRGOrThrow(canvasV2, id); const rg = selectRGOrThrow(canvasV2, id);
const rgIndex = canvasV2.regions.indexOf(rg); const rgIndex = canvasV2.regions.indexOf(rg);
const rgCount = canvasV2.regions.length; const rgCount = canvasV2.regions.length;
@ -45,14 +49,10 @@ const selectActionsValidity = createMemoizedAppSelector(
isAddPositivePromptDisabled: rg.positivePrompt === null, isAddPositivePromptDisabled: rg.positivePrompt === null,
isAddNegativePromptDisabled: rg.negativePrompt === null, isAddNegativePromptDisabled: rg.negativePrompt === null,
}; };
} }),
); [id]
);
export const RGActionsMenu = memo(({ id }: Props) => { const actions = useAppSelector(selectActionsValidity);
const { t } = useTranslation();
const dispatch = useAppDispatch();
const [onAddIPAdapter, isAddIPAdapterDisabled] = useAddIPAdapterToRGLayer(id);
const actions = useAppSelector((s) => selectActionsValidity(s, id));
const onDelete = useCallback(() => { const onDelete = useCallback(() => {
dispatch(rgDeleted({ id })); dispatch(rgDeleted({ id }));
}, [dispatch, id]); }, [dispatch, id]);