Skip to content

Commit d4ac93b

Browse files
committed
Revised streaming performance, added optimizations
1 parent f46e913 commit d4ac93b

File tree

4 files changed

+53
-37
lines changed

4 files changed

+53
-37
lines changed

spfx-latest/config/package-solution.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,16 @@
44
"name": "azure-openai-chat",
55
"title": "Azure OpenAI Chat Web Part",
66
"id": "64e358ba-f88c-4fee-9a8a-6db06299d90a",
7-
"version": "1.3.0.0",
7+
"version": "1.3.1.0",
88
"includeClientSideAssets": true,
99
"skipFeatureDeployment": true,
1010
"isDomainIsolated": false,
1111
"developer": {
1212
"name": "Paul Borisov",
13-
"websiteUrl": "https://www.linkedin.com/in/paul-borisov-b412a8171/",
13+
"websiteUrl": "https://www.linkedin.com/in/paul-borisov/",
1414
"privacyUrl": "https://github.com/Paul-Borisov/react-azure-open-ai-chat-web-part-spfx",
1515
"termsOfUseUrl": "https://github.com/Paul-Borisov/react-azure-open-ai-chat-web-part-spfx?tab=MIT-1-ov-file",
16-
"mpnId": "1848586"
16+
"mpnId": ""
1717
},
1818
"webApiPermissionRequests": [
1919
{

spfx-latest/package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

spfx-latest/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "azure-openai-chat",
3-
"version": "1.3.0",
3+
"version": "1.3.1",
44
"private": true,
55
"engines": {
66
"node": ">=16.13.0 <17.0.0 || >=18.17.1 <19.0.0"

spfx-latest/src/components/ContentPanel.tsx

Lines changed: 47 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import useChatHistory from 'hooks/useChatHistory';
55
import useStorageService from 'hooks/useStorageService';
66
import { FunctionComponent } from 'react';
77
import * as React from 'react';
8+
import { unstable_batchedUpdates } from 'react-dom';
89
import VoiceOutput from 'shared/components/Speech/VoiceOutput';
910
import Application, { GptModels } from 'shared/constants/Application';
1011
import HtmlHelper from 'shared/helpers/HtmlHelper';
@@ -164,6 +165,7 @@ const ContentPanel: FunctionComponent<IContentPanelProps> = ({ props }) => {
164165
}, [model]);
165166

166167
const elements: ContentPanelElements = React.useMemo(() => new ContentPanelElements(props), []);
168+
const refLatestResponseFromAi = React.useRef<HTMLDivElement>(null);
167169

168170
return (
169171
<>
@@ -534,12 +536,18 @@ const ContentPanel: FunctionComponent<IContentPanelProps> = ({ props }) => {
534536
} else {
535537
const assistantResponses = newChatHistory.filter((r) => r.role === 'assistant');
536538
assistantResponses[assistantResponses.length - 1].content += ChatHelper.cleanupResponseContent(response);
537-
const messageSelector = isCustomPanelOpen
538-
? `.${styles.customPanel} .${styles.message}`
539-
: `div[id="${wpId}"] .${styles.message}`;
540-
const allMessages = document.querySelectorAll(messageSelector);
541-
const lastMessage = allMessages[allMessages.length - 1];
542-
lastMessage.innerHTML += response;
539+
const queryParameters = new URLSearchParams(window.location.search);
540+
const prev = queryParameters.get('prev');
541+
if (!prev && refLatestResponseFromAi.current) {
542+
refLatestResponseFromAi.current.innerHTML += response;
543+
} else {
544+
const messageSelector = isCustomPanelOpen
545+
? `.${styles.customPanel} .${styles.message}`
546+
: `div[id="${wpId}"] .${styles.message}`;
547+
const allMessages = document.querySelectorAll(messageSelector);
548+
const lastMessage = allMessages[allMessages.length - 1];
549+
lastMessage.innerHTML += response;
550+
}
543551
}
544552
// Bug fix: the following line caused to heavy rerendering. Replaced with a lighter code above.
545553
//setChatHistory(newChatHistory); // Sets the updated array with new memory address.
@@ -549,36 +557,42 @@ const ContentPanel: FunctionComponent<IContentPanelProps> = ({ props }) => {
549557

550558
if (props.apiService.isConfigured()) {
551559
if (!props.streaming) {
552-
props.apiService.callQueryText(payload).then((response) => handleResponse(response));
560+
props.apiService.callQueryText(payload).then((response) => {
561+
unstable_batchedUpdates(() => {
562+
handleResponse(response);
563+
});
564+
});
553565
} else {
554566
let firstResponse = true;
555567
props.apiService.callQueryText(payload, true, stopSignal, (message: string, done?: boolean, isError?: boolean) => {
556-
setIsProgress(false);
557-
setIsStreamProgress(true);
558-
if (isError) {
559-
setResponseContentError(strings.TextUndeterminedError);
560-
setIsStreamProgress(false);
561-
setFormattedContent([]);
562-
} else if (!done) {
563-
if (message) {
564-
handleResponseStream(message, firstResponse);
565-
firstResponse = false;
566-
setResponseContentError(undefined);
567-
}
568-
} else {
569-
setIsStreamProgress(false);
570-
setFormattedContent([]);
571-
if (!firstResponse) {
572-
setResponseContentError(undefined);
573-
//const chatMessageId = `${styles.message}_${newChatHistory.length - 1}`;
574-
const chatMessageId = `${styles.message}_${wpId}_${newChatHistory.length - 1}`;
575-
setDisabledHighlights([...disabledHighlights.filter((id) => id !== chatMessageId)]);
576-
saveChatHistory(newChatHistory);
577-
} else {
578-
// Authentication error?
568+
unstable_batchedUpdates(() => {
569+
setIsProgress(false);
570+
setIsStreamProgress(true);
571+
if (isError) {
579572
setResponseContentError(strings.TextUndeterminedError);
573+
setIsStreamProgress(false);
574+
setFormattedContent([]);
575+
} else if (!done) {
576+
if (message) {
577+
handleResponseStream(message, firstResponse);
578+
firstResponse = false;
579+
setResponseContentError(undefined);
580+
}
581+
} else {
582+
setIsStreamProgress(false);
583+
setFormattedContent([]);
584+
if (!firstResponse) {
585+
setResponseContentError(undefined);
586+
//const chatMessageId = `${styles.message}_${newChatHistory.length - 1}`;
587+
const chatMessageId = `${styles.message}_${wpId}_${newChatHistory.length - 1}`;
588+
setDisabledHighlights([...disabledHighlights.filter((id) => id !== chatMessageId)]);
589+
saveChatHistory(newChatHistory);
590+
} else {
591+
// Authentication error?
592+
setResponseContentError(strings.TextUndeterminedError);
593+
}
580594
}
581-
}
595+
});
582596
});
583597
}
584598
} else {
@@ -703,6 +717,7 @@ const ContentPanel: FunctionComponent<IContentPanelProps> = ({ props }) => {
703717
<div
704718
id={chatMessageId}
705719
className={['ai', styles.message, isCustomPanelOpen ? styles.insidePanel : undefined].join(' ').trim()}
720+
ref={refLatestResponseFromAi}
706721
>
707722
{!disabledHighlights?.find((id) => id === chatMessageId) ? formattedRows[index] : content}
708723
</div>
@@ -711,6 +726,7 @@ const ContentPanel: FunctionComponent<IContentPanelProps> = ({ props }) => {
711726
id={chatMessageId}
712727
className={['ai', styles.message].join(' ')}
713728
dangerouslySetInnerHTML={{ __html: r.content }}
729+
ref={refLatestResponseFromAi}
714730
/>
715731
)
716732
) : (

0 commit comments

Comments
 (0)