mirror of
https://github.com/invoke-ai/InvokeAI.git
synced 2026-04-23 03:00:31 -04:00
perf(ui): optimize all selectors 1
I learned that the inline selector syntax recreates the selector function on every render: ```ts const val = useAppSelector((s) => s.slice.val) ``` Not good! Better is to create a selector outside the function and use it. Doing that for all selectors now, most of the way through now. Feels snappier.
This commit is contained in:
@@ -1,18 +1,20 @@
|
||||
import { CompositeNumberInput, CompositeSlider, FormControl, FormLabel } from '@invoke-ai/ui-library';
|
||||
import { createSelector } from '@reduxjs/toolkit';
|
||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||
import { InformationalPopover } from 'common/components/InformationalPopover/InformationalPopover';
|
||||
import { maxPromptsChanged } from 'features/dynamicPrompts/store/dynamicPromptsSlice';
|
||||
import { maxPromptsChanged, selectDynamicPromptsSlice } from 'features/dynamicPrompts/store/dynamicPromptsSlice';
|
||||
import { selectConfigSlice } from 'features/system/store/configSlice';
|
||||
import { memo, useCallback } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
const selectMaxPrompts = createSelector(selectDynamicPromptsSlice, (dynamicPrompts) => dynamicPrompts.maxPrompts);
|
||||
const selectMaxPromptsConfig = createSelector(selectConfigSlice, (config) => config.sd.dynamicPrompts.maxPrompts);
|
||||
const selectIsDisabled = createSelector(selectDynamicPromptsSlice, (dynamicPrompts) => !dynamicPrompts.combinatorial);
|
||||
|
||||
const ParamDynamicPromptsMaxPrompts = () => {
|
||||
const maxPrompts = useAppSelector((s) => s.dynamicPrompts.maxPrompts);
|
||||
const sliderMin = useAppSelector((s) => s.config.sd.dynamicPrompts.maxPrompts.sliderMin);
|
||||
const sliderMax = useAppSelector((s) => s.config.sd.dynamicPrompts.maxPrompts.sliderMax);
|
||||
const numberInputMin = useAppSelector((s) => s.config.sd.dynamicPrompts.maxPrompts.numberInputMin);
|
||||
const numberInputMax = useAppSelector((s) => s.config.sd.dynamicPrompts.maxPrompts.numberInputMax);
|
||||
const initial = useAppSelector((s) => s.config.sd.dynamicPrompts.maxPrompts.initial);
|
||||
const isDisabled = useAppSelector((s) => !s.dynamicPrompts.combinatorial);
|
||||
const maxPrompts = useAppSelector(selectMaxPrompts);
|
||||
const config = useAppSelector(selectMaxPromptsConfig);
|
||||
const isDisabled = useAppSelector(selectIsDisabled);
|
||||
const dispatch = useAppDispatch();
|
||||
const { t } = useTranslation();
|
||||
|
||||
@@ -29,18 +31,18 @@ const ParamDynamicPromptsMaxPrompts = () => {
|
||||
<FormLabel>{t('dynamicPrompts.maxPrompts')}</FormLabel>
|
||||
</InformationalPopover>
|
||||
<CompositeSlider
|
||||
min={sliderMin}
|
||||
max={sliderMax}
|
||||
min={config.sliderMin}
|
||||
max={config.sliderMax}
|
||||
value={maxPrompts}
|
||||
defaultValue={initial}
|
||||
defaultValue={config.initial}
|
||||
onChange={handleChange}
|
||||
marks
|
||||
/>
|
||||
<CompositeNumberInput
|
||||
min={numberInputMin}
|
||||
max={numberInputMax}
|
||||
min={config.numberInputMin}
|
||||
max={config.numberInputMax}
|
||||
value={maxPrompts}
|
||||
defaultValue={initial}
|
||||
defaultValue={config.initial}
|
||||
onChange={handleChange}
|
||||
/>
|
||||
</FormControl>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import type { ChakraProps } from '@invoke-ai/ui-library';
|
||||
import { Flex, FormControl, FormLabel, ListItem, OrderedList, Spinner, Text } from '@invoke-ai/ui-library';
|
||||
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
|
||||
import { createSelector } from '@reduxjs/toolkit';
|
||||
import { useAppSelector } from 'app/store/storeHooks';
|
||||
import { IAINoContentFallback } from 'common/components/IAIImageFallback';
|
||||
import { InformationalPopover } from 'common/components/InformationalPopover/InformationalPopover';
|
||||
@@ -10,17 +10,20 @@ import { memo, useMemo } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { PiWarningCircleBold } from 'react-icons/pi';
|
||||
|
||||
const selectPrompts = createMemoizedSelector(selectDynamicPromptsSlice, (dynamicPrompts) => dynamicPrompts.prompts);
|
||||
|
||||
const listItemStyles: ChakraProps['sx'] = {
|
||||
'&::marker': { color: 'base.500' },
|
||||
};
|
||||
|
||||
const selectPrompts = createSelector(selectDynamicPromptsSlice, (dynamicPrompts) => dynamicPrompts.prompts);
|
||||
const selectParsingError = createSelector(selectDynamicPromptsSlice, (dynamicPrompts) => dynamicPrompts.parsingError);
|
||||
const selectIsError = createSelector(selectDynamicPromptsSlice, (dynamicPrompts) => dynamicPrompts.isError);
|
||||
const selectIsLoading = createSelector(selectDynamicPromptsSlice, (dynamicPrompts) => dynamicPrompts.isLoading);
|
||||
|
||||
const ParamDynamicPromptsPreview = () => {
|
||||
const { t } = useTranslation();
|
||||
const parsingError = useAppSelector((s) => s.dynamicPrompts.parsingError);
|
||||
const isError = useAppSelector((s) => s.dynamicPrompts.isError);
|
||||
const isLoading = useAppSelector((s) => s.dynamicPrompts.isLoading);
|
||||
const parsingError = useAppSelector(selectParsingError);
|
||||
const isError = useAppSelector(selectIsError);
|
||||
const isLoading = useAppSelector(selectIsLoading);
|
||||
const prompts = useAppSelector(selectPrompts);
|
||||
|
||||
const label = useMemo(() => {
|
||||
|
||||
@@ -1,15 +1,22 @@
|
||||
import type { ComboboxOnChange, ComboboxOption } from '@invoke-ai/ui-library';
|
||||
import { Combobox, FormControl, FormLabel } from '@invoke-ai/ui-library';
|
||||
import { createSelector } from '@reduxjs/toolkit';
|
||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||
import { InformationalPopover } from 'common/components/InformationalPopover/InformationalPopover';
|
||||
import { isSeedBehaviour, seedBehaviourChanged } from 'features/dynamicPrompts/store/dynamicPromptsSlice';
|
||||
import {
|
||||
isSeedBehaviour,
|
||||
seedBehaviourChanged,
|
||||
selectDynamicPromptsSlice,
|
||||
} from 'features/dynamicPrompts/store/dynamicPromptsSlice';
|
||||
import { memo, useCallback, useMemo } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
const selectSeedBehaviour = createSelector(selectDynamicPromptsSlice, (dynamicPrompts) => dynamicPrompts.seedBehaviour);
|
||||
|
||||
const ParamDynamicPromptsSeedBehaviour = () => {
|
||||
const dispatch = useAppDispatch();
|
||||
const { t } = useTranslation();
|
||||
const seedBehaviour = useAppSelector((s) => s.dynamicPrompts.seedBehaviour);
|
||||
const seedBehaviour = useAppSelector(selectSeedBehaviour);
|
||||
|
||||
const options = useMemo<ComboboxOption[]>(() => {
|
||||
return [
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
import type { SystemStyleObject } from '@invoke-ai/ui-library';
|
||||
import { IconButton, spinAnimation, Tooltip } from '@invoke-ai/ui-library';
|
||||
import { createSelector } from '@reduxjs/toolkit';
|
||||
import { useAppSelector } from 'app/store/storeHooks';
|
||||
import { useDynamicPromptsModal } from 'features/dynamicPrompts/hooks/useDynamicPromptsModal';
|
||||
import { selectDynamicPromptsSlice } from 'features/dynamicPrompts/store/dynamicPromptsSlice';
|
||||
import { memo } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { BsBracesAsterisk } from 'react-icons/bs';
|
||||
@@ -10,10 +12,15 @@ const loadingStyles: SystemStyleObject = {
|
||||
svg: { animation: spinAnimation },
|
||||
};
|
||||
|
||||
const selectIsError = createSelector(selectDynamicPromptsSlice, (dynamicPrompts) =>
|
||||
Boolean(dynamicPrompts.isError || dynamicPrompts.parsingError)
|
||||
);
|
||||
const selectIsLoading = createSelector(selectDynamicPromptsSlice, (dynamicPrompts) => dynamicPrompts.isLoading);
|
||||
|
||||
export const ShowDynamicPromptsPreviewButton = memo(() => {
|
||||
const { t } = useTranslation();
|
||||
const isLoading = useAppSelector((s) => s.dynamicPrompts.isLoading);
|
||||
const isError = useAppSelector((s) => Boolean(s.dynamicPrompts.isError || s.dynamicPrompts.parsingError));
|
||||
const isLoading = useAppSelector(selectIsLoading);
|
||||
const isError = useAppSelector(selectIsError);
|
||||
const { isOpen, onOpen } = useDynamicPromptsModal();
|
||||
|
||||
return (
|
||||
|
||||
Reference in New Issue
Block a user