perf(08-01): add queueMicrotask coalescing to library store and debounce search input

- Library store notify() coalesces multiple calls per microtask tick into one subscriber notification
- Search input debounces store propagation by 150ms while keeping instant visual feedback
- Empty search input clears immediately for responsive UX
This commit is contained in:
2026-03-04 23:14:16 -05:00
parent 08793bf60d
commit 3bf66ed125
2 changed files with 24 additions and 2 deletions
@@ -10,6 +10,7 @@ import '@awesome.me/webawesome/dist/components/icon/icon.js';
@customElement('search-bar')
export class SearchBar extends LitElement {
private searchCtrl = new SearchController(this);
private searchDebounceTimer: ReturnType<typeof setTimeout> | null = null;
@query('input')
private inputEl!: HTMLInputElement;
@@ -105,7 +106,22 @@ export class SearchBar extends LitElement {
private handleInput = (e: Event) => {
const input = e.target as HTMLInputElement;
this.searchCtrl.term = input.value;
const value = input.value;
if (this.searchDebounceTimer !== null) {
clearTimeout(this.searchDebounceTimer);
this.searchDebounceTimer = null;
}
if (value === '') {
// Instant clear for responsive feedback.
this.searchCtrl.term = '';
} else {
this.searchDebounceTimer = setTimeout(() => {
this.searchDebounceTimer = null;
this.searchCtrl.term = value;
}, 150);
}
};
private handleClear = () => {
+6
View File
@@ -46,6 +46,7 @@ class LibraryStore {
};
private subscribers = new Set<Subscriber>();
private notifyScheduled = false;
constructor() {
EventsOn(Events.LibraryScanComplete, () => {
@@ -340,7 +341,12 @@ class LibraryStore {
}
private notify(): void {
if (this.notifyScheduled) return;
this.notifyScheduled = true;
queueMicrotask(() => {
this.notifyScheduled = false;
this.subscribers.forEach((callback) => callback());
});
}
// ===================================================================