Skip to content

Commit c5fbc6a

Browse files
feat(ui): rerender mitigation sweep
1 parent e496dd1 commit c5fbc6a

File tree

16 files changed

+106
-140
lines changed

16 files changed

+106
-140
lines changed

invokeai/frontend/web/src/app/App.tsx

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,13 @@ import { APP_HEIGHT, APP_WIDTH } from 'theme/util/constants';
1414
import ImageGalleryPanel from 'features/gallery/components/ImageGalleryPanel';
1515
import Lightbox from 'features/lightbox/components/Lightbox';
1616
import { useAppDispatch, useAppSelector } from './storeHooks';
17-
import { PropsWithChildren, useCallback, useEffect, useState } from 'react';
17+
import {
18+
memo,
19+
PropsWithChildren,
20+
useCallback,
21+
useEffect,
22+
useState,
23+
} from 'react';
1824
import { motion, AnimatePresence } from 'framer-motion';
1925
import Loading from 'common/components/Loading/Loading';
2026
import { useIsApplicationReady } from 'features/system/hooks/useIsApplicationReady';
@@ -23,13 +29,15 @@ import { useGlobalHotkeys } from 'common/hooks/useGlobalHotkeys';
2329
import { configChanged } from 'features/system/store/configSlice';
2430
import { useFeatureStatus } from 'features/system/hooks/useFeatureStatus';
2531

32+
const DEFAULT_CONFIG = {};
33+
2634
keepGUIAlive();
2735

2836
interface Props extends PropsWithChildren {
2937
config?: PartialAppConfig;
3038
}
3139

32-
const App = ({ config = {}, children }: Props) => {
40+
const App = ({ config = DEFAULT_CONFIG, children }: Props) => {
3341
useToastWatcher();
3442
useGlobalHotkeys();
3543

@@ -121,4 +129,4 @@ const App = ({ config = {}, children }: Props) => {
121129
);
122130
};
123131

124-
export default App;
132+
export default memo(App);

invokeai/frontend/web/src/common/components/Loading/Loading.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { Flex, Image, Spinner } from '@chakra-ui/react';
22
import InvokeAILogoImage from 'assets/images/logo.png';
3+
import { memo } from 'react';
34

45
// This component loads before the theme so we cannot use theme tokens here
56

@@ -29,4 +30,4 @@ const Loading = () => {
2930
);
3031
};
3132

32-
export default Loading;
33+
export default memo(Loading);

invokeai/frontend/web/src/common/util/getUrl.ts

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { RootState } from 'app/store';
22
import { useAppSelector } from 'app/storeHooks';
3+
import { useCallback } from 'react';
34
import { OpenAPI } from 'services/api';
45

56
export const getUrlAlt = (url: string, shouldTransformUrls: boolean) => {
@@ -15,14 +16,19 @@ export const useGetUrl = () => {
1516
(state: RootState) => state.config.shouldTransformUrls
1617
);
1718

18-
return {
19-
shouldTransformUrls,
20-
getUrl: (url?: string) => {
19+
const getUrl = useCallback(
20+
(url?: string) => {
2121
if (OpenAPI.BASE && shouldTransformUrls) {
2222
return [OpenAPI.BASE, url].join('/');
2323
}
2424

2525
return url;
2626
},
27+
[shouldTransformUrls]
28+
);
29+
30+
return {
31+
shouldTransformUrls,
32+
getUrl,
2733
};
2834
};

invokeai/frontend/web/src/features/gallery/components/CurrentImageButtons.tsx

Lines changed: 30 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -163,16 +163,16 @@ const CurrentImageButtons = (props: CurrentImageButtonsProps) => {
163163
const { t } = useTranslation();
164164
const setBothPrompts = useSetBothPrompts();
165165

166-
const handleClickUseAsInitialImage = () => {
166+
const handleClickUseAsInitialImage = useCallback(() => {
167167
if (!image) return;
168168
if (isLightboxOpen) dispatch(setIsLightboxOpen(false));
169169
dispatch(initialImageSelected(image.name));
170170
// dispatch(setInitialImage(currentImage));
171171

172172
// dispatch(setActiveTab('img2img'));
173-
};
173+
}, [dispatch, image, isLightboxOpen]);
174174

175-
const handleCopyImage = async () => {
175+
const handleCopyImage = useCallback(async () => {
176176
if (!image?.url) {
177177
return;
178178
}
@@ -194,9 +194,9 @@ const CurrentImageButtons = (props: CurrentImageButtonsProps) => {
194194
duration: 2500,
195195
isClosable: true,
196196
});
197-
};
197+
}, [getUrl, t, image?.url, toast]);
198198

199-
const handleCopyImageLink = () => {
199+
const handleCopyImageLink = useCallback(() => {
200200
const url = image
201201
? shouldTransformUrls
202202
? getUrl(image.url)
@@ -215,7 +215,7 @@ const CurrentImageButtons = (props: CurrentImageButtonsProps) => {
215215
isClosable: true,
216216
});
217217
});
218-
};
218+
}, [toast, shouldTransformUrls, getUrl, t, image]);
219219

220220
useHotkeys(
221221
'shift+i',
@@ -241,11 +241,11 @@ const CurrentImageButtons = (props: CurrentImageButtonsProps) => {
241241
[image]
242242
);
243243

244-
const handlePreviewVisibility = () => {
244+
const handlePreviewVisibility = useCallback(() => {
245245
dispatch(setShouldHidePreview(!shouldHidePreview));
246-
};
246+
}, [dispatch, shouldHidePreview]);
247247

248-
const handleClickUseAllParameters = () => {
248+
const handleClickUseAllParameters = useCallback(() => {
249249
if (!image) return;
250250
// selectedImage.metadata &&
251251
// dispatch(setAllParameters(selectedImage.metadata));
@@ -254,7 +254,7 @@ const CurrentImageButtons = (props: CurrentImageButtonsProps) => {
254254
// } else if (selectedImage.metadata?.image.type === 'txt2img') {
255255
// dispatch(setActiveTab('txt2img'));
256256
// }
257-
};
257+
}, [image]);
258258

259259
useHotkeys(
260260
'a',
@@ -338,9 +338,9 @@ const CurrentImageButtons = (props: CurrentImageButtonsProps) => {
338338
[image]
339339
);
340340

341-
const handleClickUpscale = () => {
341+
const handleClickUpscale = useCallback(() => {
342342
// selectedImage && dispatch(runESRGAN(selectedImage));
343-
};
343+
}, []);
344344

345345
useHotkeys(
346346
'Shift+U',
@@ -369,9 +369,9 @@ const CurrentImageButtons = (props: CurrentImageButtonsProps) => {
369369
]
370370
);
371371

372-
const handleClickFixFaces = () => {
372+
const handleClickFixFaces = useCallback(() => {
373373
// selectedImage && dispatch(runFacetool(selectedImage));
374-
};
374+
}, []);
375375

376376
useHotkeys(
377377
'Shift+R',
@@ -401,10 +401,12 @@ const CurrentImageButtons = (props: CurrentImageButtonsProps) => {
401401
]
402402
);
403403

404-
const handleClickShowImageDetails = () =>
405-
dispatch(setShouldShowImageDetails(!shouldShowImageDetails));
404+
const handleClickShowImageDetails = useCallback(
405+
() => dispatch(setShouldShowImageDetails(!shouldShowImageDetails)),
406+
[dispatch, shouldShowImageDetails]
407+
);
406408

407-
const handleSendToCanvas = () => {
409+
const handleSendToCanvas = useCallback(() => {
408410
if (!image) return;
409411
if (isLightboxOpen) dispatch(setIsLightboxOpen(false));
410412

@@ -421,7 +423,7 @@ const CurrentImageButtons = (props: CurrentImageButtonsProps) => {
421423
duration: 2500,
422424
isClosable: true,
423425
});
424-
};
426+
}, [image, isLightboxOpen, dispatch, activeTabName, toast, t]);
425427

426428
useHotkeys(
427429
'i',
@@ -440,19 +442,19 @@ const CurrentImageButtons = (props: CurrentImageButtonsProps) => {
440442
[image, shouldShowImageDetails]
441443
);
442444

443-
const handleInitiateDelete = () => {
445+
const handleDelete = useCallback(() => {
446+
if (canDeleteImage && image) {
447+
dispatch(imageDeleted({ imageType: image.type, imageName: image.name }));
448+
}
449+
}, [image, canDeleteImage, dispatch]);
450+
451+
const handleInitiateDelete = useCallback(() => {
444452
if (shouldConfirmOnDelete) {
445453
onDeleteDialogOpen();
446454
} else {
447455
handleDelete();
448456
}
449-
};
450-
451-
const handleDelete = () => {
452-
if (canDeleteImage && image) {
453-
dispatch(imageDeleted({ imageType: image.type, imageName: image.name }));
454-
}
455-
};
457+
}, [shouldConfirmOnDelete, onDeleteDialogOpen, handleDelete]);
456458

457459
useHotkeys('delete', handleInitiateDelete, [
458460
image,
@@ -461,9 +463,9 @@ const CurrentImageButtons = (props: CurrentImageButtonsProps) => {
461463
isProcessing,
462464
]);
463465

464-
const handleLightBox = () => {
466+
const handleLightBox = useCallback(() => {
465467
dispatch(setIsLightboxOpen(!isLightboxOpen));
466-
};
468+
}, [dispatch, isLightboxOpen]);
467469

468470
return (
469471
<>

invokeai/frontend/web/src/features/gallery/components/CurrentImagePreview.tsx

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import CurrentImageFallback from './CurrentImageFallback';
1111
import ImageMetadataViewer from './ImageMetaDataViewer/ImageMetadataViewer';
1212
import NextPrevImageButtons from './NextPrevImageButtons';
1313
import CurrentImageHidden from './CurrentImageHidden';
14+
import { memo } from 'react';
1415

1516
export const imagesSelector = createSelector(
1617
[uiSelector, selectedImageSelector, systemSelector],
@@ -50,7 +51,7 @@ export const imagesSelector = createSelector(
5051
}
5152
);
5253

53-
export default function CurrentImagePreview() {
54+
const CurrentImagePreview = () => {
5455
const { shouldShowImageDetails, imageToDisplay, shouldHidePreview } =
5556
useAppSelector(imagesSelector);
5657
const { getUrl } = useGetUrl();
@@ -115,4 +116,6 @@ export default function CurrentImagePreview() {
115116
)}
116117
</Flex>
117118
);
118-
}
119+
};
120+
121+
export default memo(CurrentImagePreview);

invokeai/frontend/web/src/features/gallery/components/ImageGalleryPanel.tsx

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import { requestCanvasRescale } from 'features/canvas/store/thunks/requestCanvas
2828
import { lightboxSelector } from 'features/lightbox/store/lightboxSelectors';
2929
import useResolution from 'common/hooks/useResolution';
3030
import { Flex } from '@chakra-ui/react';
31+
import { memo } from 'react';
3132

3233
const GALLERY_TAB_WIDTHS: Record<
3334
InvokeTabName,
@@ -72,7 +73,7 @@ const galleryPanelSelector = createSelector(
7273
}
7374
);
7475

75-
export default function ImageGalleryPanel() {
76+
export const ImageGalleryPanel = () => {
7677
const dispatch = useAppDispatch();
7778
const {
7879
shouldPinGallery,
@@ -232,4 +233,6 @@ export default function ImageGalleryPanel() {
232233
};
233234

234235
return renderImageGallery();
235-
}
236+
};
237+
238+
export default memo(ImageGalleryPanel);

invokeai/frontend/web/src/features/parameters/components/ProcessButtons/CancelButton.tsx

Lines changed: 2 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,12 @@ import IAIIconButton, {
66
import { systemSelector } from 'features/system/store/systemSelectors';
77
import {
88
SystemState,
9-
setCancelAfter,
10-
setCancelType,
119
cancelScheduled,
1210
cancelTypeChanged,
1311
CancelType,
1412
} from 'features/system/store/systemSlice';
1513
import { isEqual } from 'lodash';
16-
import { useEffect, useCallback, memo } from 'react';
14+
import { useCallback, memo } from 'react';
1715
import {
1816
ButtonSpinner,
1917
ButtonGroup,
@@ -27,16 +25,9 @@ import {
2725

2826
import { useHotkeys } from 'react-hotkeys-hook';
2927
import { useTranslation } from 'react-i18next';
30-
import {
31-
MdArrowDropDown,
32-
MdArrowDropUp,
33-
MdCancel,
34-
MdCancelScheduleSend,
35-
} from 'react-icons/md';
28+
import { MdCancel, MdCancelScheduleSend } from 'react-icons/md';
3629

37-
import IAISimpleMenu from 'common/components/IAISimpleMenu';
3830
import { sessionCanceled } from 'services/thunks/session';
39-
import { FaChevronDown } from 'react-icons/fa';
4031
import { BiChevronDown } from 'react-icons/bi';
4132

4233
const cancelButtonSelector = createSelector(
@@ -48,8 +39,6 @@ const cancelButtonSelector = createSelector(
4839
isCancelable: system.isCancelable,
4940
currentIteration: system.currentIteration,
5041
totalIterations: system.totalIterations,
51-
// cancelType: system.cancelOptions.cancelType,
52-
// cancelAfter: system.cancelOptions.cancelAfter,
5342
sessionId: system.sessionId,
5443
cancelType: system.cancelType,
5544
isCancelScheduled: system.isCancelScheduled,
@@ -75,11 +64,8 @@ const CancelButton = (
7564
isProcessing,
7665
isConnected,
7766
isCancelable,
78-
currentIteration,
79-
totalIterations,
8067
cancelType,
8168
isCancelScheduled,
82-
// cancelAfter,
8369
sessionId,
8470
} = useAppSelector(cancelButtonSelector);
8571

@@ -105,7 +91,6 @@ const CancelButton = (
10591
},
10692
[dispatch]
10793
);
108-
// const isCancelScheduled = cancelAfter === null ? false : true;
10994

11095
useHotkeys(
11196
'shift+x',
@@ -117,23 +102,6 @@ const CancelButton = (
117102
[isConnected, isProcessing, isCancelable]
118103
);
119104

120-
// useEffect(() => {
121-
// if (cancelAfter !== null && cancelAfter < currentIteration) {
122-
// handleClickCancel();
123-
// }
124-
// }, [cancelAfter, currentIteration, handleClickCancel]);
125-
126-
// const cancelMenuItems = [
127-
// {
128-
// item: t('parameters.cancel.immediate'),
129-
// onClick: () => dispatch(cancelTypeChanged('immediate')),
130-
// },
131-
// {
132-
// item: t('parameters.cancel.schedule'),
133-
// onClick: () => dispatch(cancelTypeChanged('scheduled')),
134-
// },
135-
// ];
136-
137105
return (
138106
<ButtonGroup isAttached width={btnGroupWidth}>
139107
{cancelType === 'immediate' ? (

0 commit comments

Comments
 (0)