chore: memoize components (#607)
This commit is contained in:
parent
906d7d34da
commit
3df0fd4c0f
6 changed files with 123 additions and 53 deletions
|
|
@ -97,12 +97,10 @@ function PureBlockActions({
|
||||||
}
|
}
|
||||||
|
|
||||||
export const BlockActions = memo(PureBlockActions, (prevProps, nextProps) => {
|
export const BlockActions = memo(PureBlockActions, (prevProps, nextProps) => {
|
||||||
if (
|
if (prevProps.block.status !== nextProps.block.status) return false;
|
||||||
prevProps.block.status === 'streaming' &&
|
if (prevProps.currentVersionIndex !== nextProps.currentVersionIndex)
|
||||||
nextProps.block.status === 'streaming'
|
return false;
|
||||||
) {
|
if (prevProps.isCurrentVersion !== nextProps.isCurrentVersion) return false;
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
return true;
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -14,8 +14,10 @@ import {
|
||||||
TooltipProvider,
|
TooltipProvider,
|
||||||
TooltipTrigger,
|
TooltipTrigger,
|
||||||
} from './ui/tooltip';
|
} from './ui/tooltip';
|
||||||
|
import { memo } from 'react';
|
||||||
|
import equal from 'fast-deep-equal';
|
||||||
|
|
||||||
export function MessageActions({
|
export function PureMessageActions({
|
||||||
chatId,
|
chatId,
|
||||||
message,
|
message,
|
||||||
vote,
|
vote,
|
||||||
|
|
@ -164,3 +166,13 @@ export function MessageActions({
|
||||||
</TooltipProvider>
|
</TooltipProvider>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const MessageActions = memo(
|
||||||
|
PureMessageActions,
|
||||||
|
(prevProps, nextProps) => {
|
||||||
|
if (!equal(prevProps.vote, nextProps.vote)) return false;
|
||||||
|
if (prevProps.isLoading !== nextProps.isLoading) return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
|
||||||
|
|
@ -223,9 +223,16 @@ export const PreviewMessage = memo(
|
||||||
PurePreviewMessage,
|
PurePreviewMessage,
|
||||||
(prevProps, nextProps) => {
|
(prevProps, nextProps) => {
|
||||||
if (prevProps.isLoading !== nextProps.isLoading) return false;
|
if (prevProps.isLoading !== nextProps.isLoading) return false;
|
||||||
if (prevProps.isLoading && nextProps.isLoading) return false;
|
if (prevProps.message.content !== nextProps.message.content) return false;
|
||||||
if (prevProps.message.content && nextProps.message.content) return false;
|
if (
|
||||||
|
!equal(
|
||||||
|
prevProps.message.toolInvocations,
|
||||||
|
nextProps.message.toolInvocations,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
return false;
|
||||||
if (!equal(prevProps.vote, nextProps.vote)) return false;
|
if (!equal(prevProps.vote, nextProps.vote)) return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ import { Overview } from './overview';
|
||||||
import { UIBlock } from './block';
|
import { UIBlock } from './block';
|
||||||
import { Dispatch, memo, SetStateAction } from 'react';
|
import { Dispatch, memo, SetStateAction } from 'react';
|
||||||
import { Vote } from '@/lib/db/schema';
|
import { Vote } from '@/lib/db/schema';
|
||||||
|
import equal from 'fast-deep-equal';
|
||||||
|
|
||||||
interface MessagesProps {
|
interface MessagesProps {
|
||||||
chatId: string;
|
chatId: string;
|
||||||
|
|
@ -74,15 +75,11 @@ function PureMessages({
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function areEqual(prevProps: MessagesProps, nextProps: MessagesProps) {
|
export const Messages = memo(PureMessages, (prevProps, nextProps) => {
|
||||||
if (
|
if (prevProps.isLoading !== nextProps.isLoading) return false;
|
||||||
prevProps.block.status === 'streaming' &&
|
if (prevProps.isLoading && nextProps.isLoading) return false;
|
||||||
nextProps.block.status === 'streaming'
|
if (prevProps.messages.length !== nextProps.messages.length) return false;
|
||||||
) {
|
if (!equal(prevProps.votes, nextProps.votes)) return false;
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
return true;
|
||||||
}
|
});
|
||||||
|
|
||||||
export const Messages = memo(PureMessages, areEqual);
|
|
||||||
|
|
|
||||||
|
|
@ -247,40 +247,16 @@ function PureMultimodalInput({
|
||||||
/>
|
/>
|
||||||
|
|
||||||
{isLoading ? (
|
{isLoading ? (
|
||||||
<Button
|
<StopButton stop={stop} setMessages={setMessages} />
|
||||||
className="rounded-full p-1.5 h-fit absolute bottom-2 right-2 m-0.5 border dark:border-zinc-600"
|
|
||||||
onClick={(event) => {
|
|
||||||
event.preventDefault();
|
|
||||||
stop();
|
|
||||||
setMessages((messages) => sanitizeUIMessages(messages));
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<StopIcon size={14} />
|
|
||||||
</Button>
|
|
||||||
) : (
|
) : (
|
||||||
<Button
|
<SendButton
|
||||||
className="rounded-full p-1.5 h-fit absolute bottom-2 right-2 m-0.5 border dark:border-zinc-600"
|
input={input}
|
||||||
onClick={(event) => {
|
submitForm={submitForm}
|
||||||
event.preventDefault();
|
uploadQueue={uploadQueue}
|
||||||
submitForm();
|
/>
|
||||||
}}
|
|
||||||
disabled={input.length === 0 || uploadQueue.length > 0}
|
|
||||||
>
|
|
||||||
<ArrowUpIcon size={14} />
|
|
||||||
</Button>
|
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<Button
|
<AttachmentsButton fileInputRef={fileInputRef} isLoading={isLoading} />
|
||||||
className="rounded-full p-1.5 h-fit absolute bottom-2 right-11 m-0.5 dark:border-zinc-700"
|
|
||||||
onClick={(event) => {
|
|
||||||
event.preventDefault();
|
|
||||||
fileInputRef.current?.click();
|
|
||||||
}}
|
|
||||||
variant="outline"
|
|
||||||
disabled={isLoading}
|
|
||||||
>
|
|
||||||
<PaperclipIcon size={14} />
|
|
||||||
</Button>
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -295,3 +271,80 @@ export const MultimodalInput = memo(
|
||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
function PureAttachmentsButton({
|
||||||
|
fileInputRef,
|
||||||
|
isLoading,
|
||||||
|
}: {
|
||||||
|
fileInputRef: React.MutableRefObject<HTMLInputElement | null>;
|
||||||
|
isLoading: boolean;
|
||||||
|
}) {
|
||||||
|
return (
|
||||||
|
<Button
|
||||||
|
className="rounded-full p-1.5 h-fit absolute bottom-2 right-11 m-0.5 dark:border-zinc-700"
|
||||||
|
onClick={(event) => {
|
||||||
|
event.preventDefault();
|
||||||
|
fileInputRef.current?.click();
|
||||||
|
}}
|
||||||
|
variant="outline"
|
||||||
|
disabled={isLoading}
|
||||||
|
>
|
||||||
|
<PaperclipIcon size={14} />
|
||||||
|
</Button>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const AttachmentsButton = memo(PureAttachmentsButton);
|
||||||
|
|
||||||
|
function PureStopButton({
|
||||||
|
stop,
|
||||||
|
setMessages,
|
||||||
|
}: {
|
||||||
|
stop: () => void;
|
||||||
|
setMessages: Dispatch<SetStateAction<Array<Message>>>;
|
||||||
|
}) {
|
||||||
|
return (
|
||||||
|
<Button
|
||||||
|
className="rounded-full p-1.5 h-fit absolute bottom-2 right-2 m-0.5 border dark:border-zinc-600"
|
||||||
|
onClick={(event) => {
|
||||||
|
event.preventDefault();
|
||||||
|
stop();
|
||||||
|
setMessages((messages) => sanitizeUIMessages(messages));
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<StopIcon size={14} />
|
||||||
|
</Button>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const StopButton = memo(PureStopButton);
|
||||||
|
|
||||||
|
function PureSendButton({
|
||||||
|
submitForm,
|
||||||
|
input,
|
||||||
|
uploadQueue,
|
||||||
|
}: {
|
||||||
|
submitForm: () => void;
|
||||||
|
input: string;
|
||||||
|
uploadQueue: Array<string>;
|
||||||
|
}) {
|
||||||
|
return (
|
||||||
|
<Button
|
||||||
|
className="rounded-full p-1.5 h-fit absolute bottom-2 right-2 m-0.5 border dark:border-zinc-600"
|
||||||
|
onClick={(event) => {
|
||||||
|
event.preventDefault();
|
||||||
|
submitForm();
|
||||||
|
}}
|
||||||
|
disabled={input.length === 0 || uploadQueue.length > 0}
|
||||||
|
>
|
||||||
|
<ArrowUpIcon size={14} />
|
||||||
|
</Button>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const SendButton = memo(PureSendButton, (prevProps, nextProps) => {
|
||||||
|
if (prevProps.uploadQueue.length !== nextProps.uploadQueue.length)
|
||||||
|
return false;
|
||||||
|
if (!prevProps.input !== !nextProps.input) return false;
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
|
|
||||||
|
|
@ -469,5 +469,8 @@ const PureToolbar = ({
|
||||||
};
|
};
|
||||||
|
|
||||||
export const Toolbar = memo(PureToolbar, (prevProps, nextProps) => {
|
export const Toolbar = memo(PureToolbar, (prevProps, nextProps) => {
|
||||||
return equal(prevProps, nextProps);
|
if (prevProps.isLoading !== nextProps.isLoading) return false;
|
||||||
|
if (prevProps.isToolbarVisible !== nextProps.isToolbarVisible) return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
});
|
});
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue