perf: replace JSON.stringify equality with fast-deep-equal (#23370)

This commit is contained in:
Algorithm5838
2026-04-17 14:22:06 +09:00
committed by GitHub
parent c5276f62d0
commit e5f31c2e14
6 changed files with 10 additions and 8 deletions
+1 -1
View File
@@ -54,6 +54,7 @@
"dayjs": "^1.11.10", "dayjs": "^1.11.10",
"dompurify": "^3.2.6", "dompurify": "^3.2.6",
"eventsource-parser": "^1.1.2", "eventsource-parser": "^1.1.2",
"fast-deep-equal": "^3.1.3",
"file-saver": "^2.0.5", "file-saver": "^2.0.5",
"focus-trap": "^7.6.4", "focus-trap": "^7.6.4",
"fuse.js": "^7.0.0", "fuse.js": "^7.0.0",
@@ -8462,7 +8463,6 @@
"version": "3.1.3", "version": "3.1.3",
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
"integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
"dev": true,
"license": "MIT" "license": "MIT"
}, },
"node_modules/fast-fifo": { "node_modules/fast-fifo": {
+1
View File
@@ -98,6 +98,7 @@
"dayjs": "^1.11.10", "dayjs": "^1.11.10",
"dompurify": "^3.2.6", "dompurify": "^3.2.6",
"eventsource-parser": "^1.1.2", "eventsource-parser": "^1.1.2",
"fast-deep-equal": "^3.1.3",
"file-saver": "^2.0.5", "file-saver": "^2.0.5",
"focus-trap": "^7.6.4", "focus-trap": "^7.6.4",
"fuse.js": "^7.0.0", "fuse.js": "^7.0.0",
@@ -19,6 +19,7 @@
import localizedFormat from 'dayjs/plugin/localizedFormat'; import localizedFormat from 'dayjs/plugin/localizedFormat';
import ProfileImage from './ProfileImage.svelte'; import ProfileImage from './ProfileImage.svelte';
import { WEBUI_BASE_URL } from '$lib/constants'; import { WEBUI_BASE_URL } from '$lib/constants';
import equal from 'fast-deep-equal';
const i18n = getContext('i18n'); const i18n = getContext('i18n');
dayjs.extend(localizedFormat); dayjs.extend(localizedFormat);
@@ -66,7 +67,7 @@
if (source) { if (source) {
if (message.content !== source.content || message.done !== source.done) { if (message.content !== source.content || message.done !== source.done) {
message = structuredClone(source); message = structuredClone(source);
} else if (JSON.stringify(message) !== JSON.stringify(source)) { } else if (!equal(message, source)) {
message = structuredClone(source); message = structuredClone(source);
} }
} }
@@ -37,6 +37,7 @@
removeAllDetails removeAllDetails
} from '$lib/utils'; } from '$lib/utils';
import { WEBUI_API_BASE_URL, WEBUI_BASE_URL } from '$lib/constants'; import { WEBUI_API_BASE_URL, WEBUI_BASE_URL } from '$lib/constants';
import equal from 'fast-deep-equal';
import Name from './Name.svelte'; import Name from './Name.svelte';
import ProfileImage from './ProfileImage.svelte'; import ProfileImage from './ProfileImage.svelte';
@@ -127,7 +128,7 @@
// Avoids 2x O(n) JSON.stringify calls that are always true during streaming anyway // Avoids 2x O(n) JSON.stringify calls that are always true during streaming anyway
if (message.content !== source.content || message.done !== source.done) { if (message.content !== source.content || message.done !== source.done) {
message = structuredClone(source); message = structuredClone(source);
} else if (JSON.stringify(message) !== JSON.stringify(source)) { } else if (!equal(message, source)) {
// Slow path: full comparison for infrequent changes (sources, annotations, status, etc.) // Slow path: full comparison for infrequent changes (sources, annotations, status, etc.)
message = structuredClone(source); message = structuredClone(source);
} }
@@ -3,6 +3,7 @@
const i18n = getContext('i18n'); const i18n = getContext('i18n');
import StatusItem from './StatusHistory/StatusItem.svelte'; import StatusItem from './StatusHistory/StatusItem.svelte';
import equal from 'fast-deep-equal';
export let statusHistory = []; export let statusHistory = [];
export let expand = false; export let expand = false;
@@ -21,10 +22,7 @@
status = history.at(-1); status = history.at(-1);
} }
$: if ( $: if (!equal(statusHistory, history)) {
statusHistory.length !== history.length ||
JSON.stringify(statusHistory) !== JSON.stringify(history)
) {
history = statusHistory; history = statusHistory;
} }
</script> </script>
@@ -7,6 +7,7 @@
import { user as _user } from '$lib/stores'; import { user as _user } from '$lib/stores';
import { copyToClipboard as _copyToClipboard, formatDate } from '$lib/utils'; import { copyToClipboard as _copyToClipboard, formatDate } from '$lib/utils';
import { WEBUI_API_BASE_URL, WEBUI_BASE_URL } from '$lib/constants'; import { WEBUI_API_BASE_URL, WEBUI_BASE_URL } from '$lib/constants';
import equal from 'fast-deep-equal';
import Name from './Name.svelte'; import Name from './Name.svelte';
import ProfileImage from './ProfileImage.svelte'; import ProfileImage from './ProfileImage.svelte';
@@ -58,7 +59,7 @@
if (source) { if (source) {
if (message.content !== source.content) { if (message.content !== source.content) {
message = structuredClone(source); message = structuredClone(source);
} else if (JSON.stringify(message) !== JSON.stringify(source)) { } else if (!equal(message, source)) {
message = structuredClone(source); message = structuredClone(source);
} }
} }