From 2c1227844489f6dfceccc5ac8e0efc8e77efa407 Mon Sep 17 00:00:00 2001 From: Classic298 <27028174+Classic298@users.noreply.github.com> Date: Tue, 27 Jan 2026 21:33:23 +0100 Subject: [PATCH] perf: Debounce various Database Endpoints for less Database Queries and better Backend performance (#20982) * Update KnowledgeSelector.svelte * Update KnowledgeSelector.svelte * Update Users.svelte * Update MemberSelector.svelte * Update MemberSelector.svelte * Update Knowledge.svelte * Update Knowledge.svelte * Update Notes.svelte * Update Knowledge.svelte * Update Prompts.svelte * Update Tools.svelte * Update Tools.svelte * Update Prompts.svelte * Update Prompts.svelte * Update Prompts.svelte * Update Functions.svelte * Update UserList.svelte * Update Functions.svelte * Update Prompts.svelte * Update UserList.svelte --- src/lib/components/admin/Functions.svelte | 21 ++++++++++++------- .../admin/Users/Groups/Users.svelte | 17 +++++++++++---- .../components/admin/Users/UserList.svelte | 17 +++++++++++---- .../MessageInput/Commands/Knowledge.svelte | 12 +++++++++-- .../chat/MessageInput/Commands/Prompts.svelte | 15 ++++++++++++- src/lib/components/notes/Notes.svelte | 12 ++++++++++- src/lib/components/workspace/Knowledge.svelte | 18 ++++++++++++++-- .../Models/Knowledge/KnowledgeSelector.svelte | 15 +++++++++---- src/lib/components/workspace/Prompts.svelte | 10 +++++++-- src/lib/components/workspace/Tools.svelte | 17 +++++++++++++-- .../workspace/common/MemberSelector.svelte | 16 ++++++++++++-- 11 files changed, 139 insertions(+), 31 deletions(-) diff --git a/src/lib/components/admin/Functions.svelte b/src/lib/components/admin/Functions.svelte index 06de4576b2..48c1863e74 100644 --- a/src/lib/components/admin/Functions.svelte +++ b/src/lib/components/admin/Functions.svelte @@ -4,7 +4,7 @@ const { saveAs } = fileSaver; import { WEBUI_NAME, config, functions as _functions, models, settings, user } from '$lib/stores'; - import { onMount, getContext, tick } from 'svelte'; + import { onMount, getContext, tick, onDestroy } from 'svelte'; import { goto } from '$app/navigation'; import { @@ -53,6 +53,7 @@ let viewOption = ''; let query = ''; + let searchDebounceTimer: ReturnType; let selectedTag = ''; let selectedType = ''; @@ -70,12 +71,14 @@ let functions = null; let filteredItems = []; - $: if ( - functions && - query !== undefined && - selectedType !== undefined && - viewOption !== undefined - ) { + $: if (query !== undefined) { + clearTimeout(searchDebounceTimer); + searchDebounceTimer = setTimeout(() => { + setFilteredItems(); + }, 300); + } + + $: if (functions && selectedType !== undefined && viewOption !== undefined) { setFilteredItems(); } @@ -239,6 +242,10 @@ window.removeEventListener('blur-sm', onBlur); }; }); + + onDestroy(() => { + clearTimeout(searchDebounceTimer); + }); diff --git a/src/lib/components/admin/Users/Groups/Users.svelte b/src/lib/components/admin/Users/Groups/Users.svelte index 76f398d71c..ac1daade87 100644 --- a/src/lib/components/admin/Users/Groups/Users.svelte +++ b/src/lib/components/admin/Users/Groups/Users.svelte @@ -1,5 +1,5 @@
diff --git a/src/lib/components/admin/Users/UserList.svelte b/src/lib/components/admin/Users/UserList.svelte index 93490be59e..467adc5ee2 100644 --- a/src/lib/components/admin/Users/UserList.svelte +++ b/src/lib/components/admin/Users/UserList.svelte @@ -2,7 +2,7 @@ import { WEBUI_API_BASE_URL, WEBUI_BASE_URL } from '$lib/constants'; import { WEBUI_NAME, config, user, showSidebar } from '$lib/stores'; import { goto } from '$app/navigation'; - import { onMount, getContext } from 'svelte'; + import { onMount, getContext, onDestroy } from 'svelte'; import dayjs from 'dayjs'; import relativeTime from 'dayjs/plugin/relativeTime'; @@ -43,6 +43,7 @@ let total = null; let query = ''; + let searchDebounceTimer: ReturnType; let orderBy = 'created_at'; // default sort key let direction = 'asc'; // default sort order @@ -97,13 +98,21 @@ } }; - $: if (query) { - page = 1; + $: if (query !== undefined) { + clearTimeout(searchDebounceTimer); + searchDebounceTimer = setTimeout(() => { + page = 1; + getUserList(); + }, 300); } - $: if (query !== null && page !== null && orderBy !== null && direction !== null) { + $: if (page !== null && orderBy !== null && direction !== null) { getUserList(); } + + onDestroy(() => { + clearTimeout(searchDebounceTimer); + }); ; export let filteredItems = []; $: filteredItems = [ @@ -69,10 +70,17 @@ $: items = [...folderItems, ...knowledgeItems, ...fileItems]; - $: if (query !== null) { - getItems(); + $: if (query !== undefined) { + clearTimeout(searchDebounceTimer); + searchDebounceTimer = setTimeout(() => { + getItems(); + }, 200); } + onDestroy(() => { + clearTimeout(searchDebounceTimer); + }); + const getItems = () => { getFolderItems(); getKnowledgeItems(); diff --git a/src/lib/components/chat/MessageInput/Commands/Prompts.svelte b/src/lib/components/chat/MessageInput/Commands/Prompts.svelte index 0da053993f..da0be01615 100644 --- a/src/lib/components/chat/MessageInput/Commands/Prompts.svelte +++ b/src/lib/components/chat/MessageInput/Commands/Prompts.svelte @@ -11,9 +11,22 @@ let selectedPromptIdx = 0; export let filteredItems = []; + let searchDebounceTimer: ReturnType; + let debouncedQuery = ''; + + $: if (query !== undefined) { + clearTimeout(searchDebounceTimer); + searchDebounceTimer = setTimeout(() => { + debouncedQuery = query; + }, 200); + } + + onDestroy(() => { + clearTimeout(searchDebounceTimer); + }); $: filteredItems = prompts - .filter((p) => p.command.toLowerCase().includes(query.toLowerCase())) + .filter((p) => p.command.toLowerCase().includes(debouncedQuery.toLowerCase())) .sort((a, b) => a.name.localeCompare(b.name)); $: if (query) { diff --git a/src/lib/components/notes/Notes.svelte b/src/lib/components/notes/Notes.svelte index 6074c7f063..3ca43e6ee1 100644 --- a/src/lib/components/notes/Notes.svelte +++ b/src/lib/components/notes/Notes.svelte @@ -60,6 +60,7 @@ let total = null; let query = ''; + let searchDebounceTimer: ReturnType; let sortKey = null; let displayOption = null; @@ -163,9 +164,17 @@ await getItemsPage(); }; + $: if (query !== undefined) { + clearTimeout(searchDebounceTimer); + searchDebounceTimer = setTimeout(() => { + if (loaded) { + init(); + } + }, 300); + } + $: if ( loaded && - query !== undefined && sortKey !== undefined && permission !== undefined && viewOption !== undefined @@ -283,6 +292,7 @@ }); onDestroy(() => { + clearTimeout(searchDebounceTimer); console.log('destroy'); const dropzoneElement = document.getElementById('notes-container'); diff --git a/src/lib/components/workspace/Knowledge.svelte b/src/lib/components/workspace/Knowledge.svelte index e93faa1554..74564f8b87 100644 --- a/src/lib/components/workspace/Knowledge.svelte +++ b/src/lib/components/workspace/Knowledge.svelte @@ -4,7 +4,7 @@ dayjs.extend(relativeTime); import { toast } from 'svelte-sonner'; - import { onMount, getContext, tick } from 'svelte'; + import { onMount, getContext, tick, onDestroy } from 'svelte'; const i18n = getContext('i18n'); import { WEBUI_NAME, knowledge, user } from '$lib/stores'; @@ -36,6 +36,7 @@ let page = 1; let query = ''; + let searchDebounceTimer: ReturnType; let viewOption = ''; let items = null; @@ -44,7 +45,20 @@ let allItemsLoaded = false; let itemsLoading = false; - $: if (loaded && query !== undefined && viewOption !== undefined) { + $: if (query !== undefined) { + clearTimeout(searchDebounceTimer); + searchDebounceTimer = setTimeout(() => { + if (loaded) { + init(); + } + }, 300); + } + + onDestroy(() => { + clearTimeout(searchDebounceTimer); + }); + + $: if (loaded && viewOption !== undefined) { init(); } diff --git a/src/lib/components/workspace/Models/Knowledge/KnowledgeSelector.svelte b/src/lib/components/workspace/Models/Knowledge/KnowledgeSelector.svelte index fa50e9047f..2d6eb0d114 100644 --- a/src/lib/components/workspace/Models/Knowledge/KnowledgeSelector.svelte +++ b/src/lib/components/workspace/Models/Knowledge/KnowledgeSelector.svelte @@ -1,8 +1,7 @@ diff --git a/src/lib/components/workspace/Tools.svelte b/src/lib/components/workspace/Tools.svelte index 7ca7437758..cd0d5c35ba 100644 --- a/src/lib/components/workspace/Tools.svelte +++ b/src/lib/components/workspace/Tools.svelte @@ -3,7 +3,7 @@ import fileSaver from 'file-saver'; const { saveAs } = fileSaver; - import { onMount, getContext, tick } from 'svelte'; + import { onMount, getContext, tick, onDestroy } from 'svelte'; const i18n = getContext('i18n'); import { WEBUI_NAME, config, prompts, tools as _tools, user } from '$lib/stores'; @@ -47,6 +47,7 @@ let showConfirm = false; let query = ''; + let searchDebounceTimer: ReturnType; let showManifestModal = false; let showValvesModal = false; @@ -62,7 +63,14 @@ let showImportModal = false; - $: if (tools && query !== undefined && viewOption !== undefined) { + $: if (query !== undefined) { + clearTimeout(searchDebounceTimer); + searchDebounceTimer = setTimeout(() => { + setFilteredItems(); + }, 300); + } + + $: if (tools && viewOption !== undefined) { setFilteredItems(); } @@ -179,11 +187,16 @@ window.addEventListener('blur-sm', onBlur); return () => { + clearTimeout(searchDebounceTimer); window.removeEventListener('keydown', onKeyDown); window.removeEventListener('keyup', onKeyUp); window.removeEventListener('blur-sm', onBlur); }; }); + + onDestroy(() => { + clearTimeout(searchDebounceTimer); + }); diff --git a/src/lib/components/workspace/common/MemberSelector.svelte b/src/lib/components/workspace/common/MemberSelector.svelte index a9bbb7149f..84c700d8f9 100644 --- a/src/lib/components/workspace/common/MemberSelector.svelte +++ b/src/lib/components/workspace/common/MemberSelector.svelte @@ -1,6 +1,6 @@