Skip to content

Commit aa5d76a

Browse files
committed
perf: replace JSON.stringify equality with fast-deep-equal
1 parent 07d80bd commit aa5d76a

6 files changed

Lines changed: 10 additions & 8 deletions

File tree

package-lock.json

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@
9898
"dayjs": "^1.11.10",
9999
"dompurify": "^3.2.6",
100100
"eventsource-parser": "^1.1.2",
101+
"fast-deep-equal": "^3.1.3",
101102
"file-saver": "^2.0.5",
102103
"focus-trap": "^7.6.4",
103104
"fuse.js": "^7.0.0",

src/lib/components/chat/Messages/MultiResponseMessages.svelte

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import localizedFormat from 'dayjs/plugin/localizedFormat';
2020
import ProfileImage from './ProfileImage.svelte';
2121
import { WEBUI_BASE_URL } from '$lib/constants';
22+
import equal from 'fast-deep-equal';
2223
const i18n = getContext('i18n');
2324
dayjs.extend(localizedFormat);
2425
@@ -66,7 +67,7 @@
6667
if (source) {
6768
if (message.content !== source.content || message.done !== source.done) {
6869
message = structuredClone(source);
69-
} else if (JSON.stringify(message) !== JSON.stringify(source)) {
70+
} else if (!equal(message, source)) {
7071
message = structuredClone(source);
7172
}
7273
}

src/lib/components/chat/Messages/ResponseMessage.svelte

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
removeAllDetails
3838
} from '$lib/utils';
3939
import { WEBUI_API_BASE_URL, WEBUI_BASE_URL } from '$lib/constants';
40+
import equal from 'fast-deep-equal';
4041
4142
import Name from './Name.svelte';
4243
import ProfileImage from './ProfileImage.svelte';
@@ -127,7 +128,7 @@
127128
// Avoids 2x O(n) JSON.stringify calls that are always true during streaming anyway
128129
if (message.content !== source.content || message.done !== source.done) {
129130
message = structuredClone(source);
130-
} else if (JSON.stringify(message) !== JSON.stringify(source)) {
131+
} else if (!equal(message, source)) {
131132
// Slow path: full comparison for infrequent changes (sources, annotations, status, etc.)
132133
message = structuredClone(source);
133134
}

src/lib/components/chat/Messages/ResponseMessage/StatusHistory.svelte

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
const i18n = getContext('i18n');
44
55
import StatusItem from './StatusHistory/StatusItem.svelte';
6+
import equal from 'fast-deep-equal';
67
export let statusHistory = [];
78
export let expand = false;
89
@@ -21,10 +22,7 @@
2122
status = history.at(-1);
2223
}
2324
24-
$: if (
25-
statusHistory.length !== history.length ||
26-
JSON.stringify(statusHistory) !== JSON.stringify(history)
27-
) {
25+
$: if (!equal(statusHistory, history)) {
2826
history = statusHistory;
2927
}
3028
</script>

src/lib/components/chat/Messages/UserMessage.svelte

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import { user as _user } from '$lib/stores';
88
import { copyToClipboard as _copyToClipboard, formatDate } from '$lib/utils';
99
import { WEBUI_API_BASE_URL, WEBUI_BASE_URL } from '$lib/constants';
10+
import equal from 'fast-deep-equal';
1011
1112
import Name from './Name.svelte';
1213
import ProfileImage from './ProfileImage.svelte';
@@ -58,7 +59,7 @@
5859
if (source) {
5960
if (message.content !== source.content) {
6061
message = structuredClone(source);
61-
} else if (JSON.stringify(message) !== JSON.stringify(source)) {
62+
} else if (!equal(message, source)) {
6263
message = structuredClone(source);
6364
}
6465
}

0 commit comments

Comments
 (0)