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:
@@ -10,6 +10,7 @@ import '@awesome.me/webawesome/dist/components/icon/icon.js';
|
|||||||
@customElement('search-bar')
|
@customElement('search-bar')
|
||||||
export class SearchBar extends LitElement {
|
export class SearchBar extends LitElement {
|
||||||
private searchCtrl = new SearchController(this);
|
private searchCtrl = new SearchController(this);
|
||||||
|
private searchDebounceTimer: ReturnType<typeof setTimeout> | null = null;
|
||||||
|
|
||||||
@query('input')
|
@query('input')
|
||||||
private inputEl!: HTMLInputElement;
|
private inputEl!: HTMLInputElement;
|
||||||
@@ -105,7 +106,22 @@ export class SearchBar extends LitElement {
|
|||||||
|
|
||||||
private handleInput = (e: Event) => {
|
private handleInput = (e: Event) => {
|
||||||
const input = e.target as HTMLInputElement;
|
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 = () => {
|
private handleClear = () => {
|
||||||
|
|||||||
@@ -46,6 +46,7 @@ class LibraryStore {
|
|||||||
};
|
};
|
||||||
|
|
||||||
private subscribers = new Set<Subscriber>();
|
private subscribers = new Set<Subscriber>();
|
||||||
|
private notifyScheduled = false;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
EventsOn(Events.LibraryScanComplete, () => {
|
EventsOn(Events.LibraryScanComplete, () => {
|
||||||
@@ -340,7 +341,12 @@ class LibraryStore {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private notify(): void {
|
private notify(): void {
|
||||||
|
if (this.notifyScheduled) return;
|
||||||
|
this.notifyScheduled = true;
|
||||||
|
queueMicrotask(() => {
|
||||||
|
this.notifyScheduled = false;
|
||||||
this.subscribers.forEach((callback) => callback());
|
this.subscribers.forEach((callback) => callback());
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// ===================================================================
|
// ===================================================================
|
||||||
|
|||||||
Reference in New Issue
Block a user