Improve Algolia search concurrency

This commit is contained in:
Mimi 2026-08-04 14:55:10 +08:00
parent 4352696dba
commit 5c7574fd3f

View File

@ -19,16 +19,13 @@ document.addEventListener('DOMContentLoaded', () => {
return result;
};
let isSearching = false;
let pendingQuery = null;
let latestSearchId = 0;
const searchAlgolia = async (searchText, page = 0) => {
if (isSearching) {
pendingQuery = { searchText, page };
return;
}
isSearching = true;
const searchAlgolia = async (searchText, page, searchId) => {
if (searchId !== latestSearchId) return;
container.setAttribute('aria-busy', 'true');
const startTime = Date.now();
try {
const result = await client.search({
requests: [{
indexName,
@ -41,6 +38,8 @@ document.addEventListener('DOMContentLoaded', () => {
highlightPostTag : '</mark>'
}]
});
if (searchId !== latestSearchId) return;
const data = result.results[0];
if (data.nbHits === 0) {
container.innerHTML = '<div class="search-result-icon"><i class="far fa-frown fa-5x"></i></div>';
@ -72,30 +71,40 @@ document.addEventListener('DOMContentLoaded', () => {
container.querySelectorAll('.page-number').forEach(element => {
element.addEventListener('click', async event => {
event.preventDefault();
await searchAlgolia(searchText, Number(element.dataset.index));
if (input.value.trim() !== searchText) return;
const searchId = ++latestSearchId;
await searchAlgolia(searchText, Number(element.dataset.index), searchId);
});
});
}
isSearching = false;
if (pendingQuery !== null && (pendingQuery.searchText !== searchText || pendingQuery.page !== page)) {
const { searchText, page } = pendingQuery;
pendingQuery = null;
searchAlgolia(searchText, page);
} catch (error) {
if (searchId !== latestSearchId) return;
console.warn('Algolia search failed:', error);
container.innerHTML = '<div class="search-result-icon"><i class="far fa-frown fa-5x"></i></div>';
} finally {
if (searchId === latestSearchId) container.removeAttribute('aria-busy');
}
};
const inputEventFunction = async () => {
const inputEventFunction = async searchId => {
if (searchId !== latestSearchId) return;
const searchText = input.value.trim();
if (searchText === '') {
container.innerHTML = '<div class="search-result-icon"><i class="fab fa-algolia fa-5x"></i></div>';
return;
}
if (searchText === '') return;
// Algolia client will automatically cache the data for same queries
await searchAlgolia(searchText, 0);
await searchAlgolia(searchText, 0, searchId);
};
const debouncedSearch = NexT.utils.debounce(inputEventFunction, 500);
input.addEventListener('input', debouncedSearch);
input.addEventListener('input', () => {
const searchId = ++latestSearchId;
if (input.value.trim() === '') {
container.removeAttribute('aria-busy');
container.innerHTML = '<div class="search-result-icon"><i class="fab fa-algolia fa-5x"></i></div>';
} else {
container.setAttribute('aria-busy', 'true');
}
debouncedSearch(searchId);
});
// Handle and trigger popup window
document.querySelectorAll('.popup-trigger').forEach(element => {