mirror of
https://github.com/next-theme/hexo-theme-next.git
synced 2026-09-14 06:50:20 +00:00
Improve Algolia search concurrency
This commit is contained in:
parent
4352696dba
commit
5c7574fd3f
51
source/js/third-party/search/algolia-search.js
vendored
51
source/js/third-party/search/algolia-search.js
vendored
@ -19,16 +19,13 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
|
|
||||||
let isSearching = false;
|
let latestSearchId = 0;
|
||||||
let pendingQuery = null;
|
|
||||||
|
|
||||||
const searchAlgolia = async (searchText, page = 0) => {
|
const searchAlgolia = async (searchText, page, searchId) => {
|
||||||
if (isSearching) {
|
if (searchId !== latestSearchId) return;
|
||||||
pendingQuery = { searchText, page };
|
container.setAttribute('aria-busy', 'true');
|
||||||
return;
|
|
||||||
}
|
|
||||||
isSearching = true;
|
|
||||||
const startTime = Date.now();
|
const startTime = Date.now();
|
||||||
|
try {
|
||||||
const result = await client.search({
|
const result = await client.search({
|
||||||
requests: [{
|
requests: [{
|
||||||
indexName,
|
indexName,
|
||||||
@ -41,6 +38,8 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
highlightPostTag : '</mark>'
|
highlightPostTag : '</mark>'
|
||||||
}]
|
}]
|
||||||
});
|
});
|
||||||
|
if (searchId !== latestSearchId) return;
|
||||||
|
|
||||||
const data = result.results[0];
|
const data = result.results[0];
|
||||||
if (data.nbHits === 0) {
|
if (data.nbHits === 0) {
|
||||||
container.innerHTML = '<div class="search-result-icon"><i class="far fa-frown fa-5x"></i></div>';
|
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 => {
|
container.querySelectorAll('.page-number').forEach(element => {
|
||||||
element.addEventListener('click', async event => {
|
element.addEventListener('click', async event => {
|
||||||
event.preventDefault();
|
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;
|
} catch (error) {
|
||||||
if (pendingQuery !== null && (pendingQuery.searchText !== searchText || pendingQuery.page !== page)) {
|
if (searchId !== latestSearchId) return;
|
||||||
const { searchText, page } = pendingQuery;
|
console.warn('Algolia search failed:', error);
|
||||||
pendingQuery = null;
|
container.innerHTML = '<div class="search-result-icon"><i class="far fa-frown fa-5x"></i></div>';
|
||||||
searchAlgolia(searchText, page);
|
} finally {
|
||||||
|
if (searchId === latestSearchId) container.removeAttribute('aria-busy');
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const inputEventFunction = async () => {
|
const inputEventFunction = async searchId => {
|
||||||
|
if (searchId !== latestSearchId) return;
|
||||||
const searchText = input.value.trim();
|
const searchText = input.value.trim();
|
||||||
if (searchText === '') {
|
if (searchText === '') return;
|
||||||
container.innerHTML = '<div class="search-result-icon"><i class="fab fa-algolia fa-5x"></i></div>';
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// Algolia client will automatically cache the data for same queries
|
// 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);
|
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
|
// Handle and trigger popup window
|
||||||
document.querySelectorAll('.popup-trigger').forEach(element => {
|
document.querySelectorAll('.popup-trigger').forEach(element => {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user