perf(ui): lora components

This commit is contained in:
psychedelicious
2025-07-04 01:39:59 +10:00
parent 5c5ac570e3
commit 987e401709
3 changed files with 38 additions and 20 deletions

View File

@@ -9,22 +9,38 @@ import {
Switch,
Text,
} from '@invoke-ai/ui-library';
import { useAppDispatch } from 'app/store/storeHooks';
import { createSelector } from '@reduxjs/toolkit';
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
import { InformationalPopover } from 'common/components/InformationalPopover/InformationalPopover';
import { loraDeleted, loraIsEnabledChanged, loraWeightChanged } from 'features/controlLayers/store/lorasSlice';
import {
loraDeleted,
loraIsEnabledChanged,
loraWeightChanged,
selectLoRAsSlice,
} from 'features/controlLayers/store/lorasSlice';
import type { LoRA } from 'features/controlLayers/store/types';
import { memo, useCallback } from 'react';
import { memo, useCallback, useMemo } from 'react';
import { PiTrashSimpleBold } from 'react-icons/pi';
import { useGetModelConfigQuery } from 'services/api/endpoints/models';
type LoRACardProps = {
lora: LoRA;
};
const marks = [-1, 0, 1, 2];
export const LoRACard = memo((props: LoRACardProps) => {
const { lora } = props;
export const LoRACard = memo((props: { id: string }) => {
const selectLoRA = useMemo(
() => createSelector(selectLoRAsSlice, ({ loras }) => loras.find(({ id }) => id === props.id)),
[props.id]
);
const lora = useAppSelector(selectLoRA);
if (!lora) {
return null;
}
return <LoRAContent lora={lora} />;
});
LoRACard.displayName = 'LoRACard';
export const LoRAContent = memo(({ lora }: { lora: LoRA }) => {
const dispatch = useAppDispatch();
const { data: loraConfig } = useGetModelConfigQuery(lora.model.key);
@@ -91,4 +107,4 @@ export const LoRACard = memo((props: LoRACardProps) => {
);
});
LoRACard.displayName = 'LoRACard';
LoRAContent.displayName = 'LoRAContent';

View File

@@ -5,19 +5,19 @@ import { selectLoRAsSlice } from 'features/controlLayers/store/lorasSlice';
import { LoRACard } from 'features/lora/components/LoRACard';
import { memo } from 'react';
const selectLoRAsArray = createMemoizedSelector(selectLoRAsSlice, (loras) => loras.loras);
const selectLoRAIds = createMemoizedSelector(selectLoRAsSlice, (loras) => loras.loras.map(({ id }) => id));
export const LoRAList = memo(() => {
const lorasArray = useAppSelector(selectLoRAsArray);
const ids = useAppSelector(selectLoRAIds);
if (!lorasArray.length) {
if (!ids.length) {
return null;
}
return (
<Flex flexWrap="wrap" gap={2}>
{lorasArray.map((lora) => (
<LoRACard key={lora.id} lora={lora} />
{ids.map((id) => (
<LoRACard key={id} id={id} />
))}
</Flex>
);

View File

@@ -1,6 +1,6 @@
import { FormControl, FormLabel } from '@invoke-ai/ui-library';
import { createSelector } from '@reduxjs/toolkit';
import { EMPTY_ARRAY } from 'app/store/constants';
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
import { InformationalPopover } from 'common/components/InformationalPopover/InformationalPopover';
import type { GroupStatusMap } from 'common/components/Picker/Picker';
@@ -13,13 +13,15 @@ import { useTranslation } from 'react-i18next';
import { useLoRAModels } from 'services/api/hooks/modelsByType';
import type { LoRAModelConfig } from 'services/api/types';
const selectLoRAs = createSelector(selectLoRAsSlice, (loras) => loras.loras);
const selectLoRAModelKeys = createMemoizedSelector(selectLoRAsSlice, ({ loras }) =>
loras.map(({ model }) => model.key)
);
const LoRASelect = () => {
const dispatch = useAppDispatch();
const [modelConfigs, { isLoading }] = useLoRAModels();
const { t } = useTranslation();
const addedLoRAs = useAppSelector(selectLoRAs);
const addedLoRAModelKeys = useAppSelector(selectLoRAModelKeys);
const currentBaseModel = useAppSelector(selectBase);
@@ -33,10 +35,10 @@ const LoRASelect = () => {
const getIsDisabled = useCallback(
(model: LoRAModelConfig): boolean => {
const isAdded = Boolean(addedLoRAs.find((lora) => lora.model.key === model.key));
const isAdded = addedLoRAModelKeys.includes(model.key);
return isAdded;
},
[addedLoRAs]
[addedLoRAModelKeys]
);
const onChange = useCallback(