-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Search: Lazy load search JS on first interaction (or after 5s)
This will reduce the QUnit homepage total uncompressed size by ~70 KB from 360KB to 290KB.
- Loading branch information
Showing
1 changed file
with
42 additions
and
8 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -12,13 +12,38 @@ | |
* https://www.jsdelivr.com/package/npm/algoliasearch | ||
* https://www.jsdelivr.com/package/npm/autocomplete.js | ||
|
||
Remember to use the 'defer' attribute. | ||
We use type="module" as a natural way to cut the mustard, | ||
executing the script only on modern browsers with ES6 support, | ||
and causing no errors on older browsers. | ||
See https://responsivenews.co.uk/post/18948466399/cutting-the-mustard | ||
{% endcomment %} | ||
<script defer src="https://cdn.jsdelivr.net/npm/[email protected]/dist/algoliasearch-lite.umd.js" integrity="sha256-YuyfhK9VEyfW6ejFiPbfOX2SELbFrgFU/8tU3MHuh60=" crossorigin="anonymous"></script> | ||
<script defer src="https://cdn.jsdelivr.net/npm/[email protected]/dist/autocomplete.min.js" integrity="sha256-YVWQosorZnr6fALvOW9VALYuInld27RkSPkElGBdCaU=" crossorigin="anonymous"></script> | ||
<script type="module"> | ||
// Await deferred scripts | ||
window.addEventListener('DOMContentLoaded', function setupSearch() { | ||
const loadSearch = () => Promise.all([ | ||
new Promise((resolve) => document.body.append(Object.assign(document.createElement('script'), { | ||
crossOrigin: 'anonymous', | ||
integrity: 'sha256-YuyfhK9VEyfW6ejFiPbfOX2SELbFrgFU/8tU3MHuh60=', | ||
src: 'https://cdn.jsdelivr.net/npm/[email protected]/dist/algoliasearch-lite.umd.js', | ||
onload: resolve | ||
}))), | ||
new Promise((resolve) => document.body.append(Object.assign(document.createElement('script'), { | ||
crossOrigin: 'anonymous', | ||
integrity: 'sha256-YVWQosorZnr6fALvOW9VALYuInld27RkSPkElGBdCaU=', | ||
src: 'https://cdn.jsdelivr.net/npm/[email protected]/dist/autocomplete.min.js', | ||
onload: resolve | ||
}))) | ||
]); | ||
let restoreFocus = false; | ||
async function setupSearch(e) { | ||
// Remember if first input happened, to restore focus as-needed since | ||
// autocomplete.js will replace the input element. | ||
// This is before "once" check, to account for input between start and end of preload | ||
restoreFocus = restoreFocus || (e && (e.type === 'click' || e.type === 'focus')); | ||
|
||
// Enforce "once" for loading scripts and configuring search field | ||
if (setupSearch.setup) return; | ||
setupSearch.setup = 1; | ||
await loadSearch(); | ||
|
||
const client = algoliasearch('{{ site.amethyst.algolia.application_id | default: site.algolia.application_id }}', '{{ site.amethyst.algolia.search_only_api_key }}'); | ||
{% if site.amethyst.algolia.sources -%} | ||
const indexSources = {{ site.amethyst.algolia.sources | jsonify }}; | ||
|
@@ -31,8 +56,10 @@ | |
const autocompleteOptions = { | ||
hint: false, | ||
ariaLabel: 'search input', | ||
// Set debug to true if you want to inspect the dropdown | ||
// Set debug to true to allow inspecting the dropdown | ||
debug: true, | ||
// Upon focus restore (see below), load suggestions if input is non-empty | ||
openOnFocus: true, | ||
templates: { | ||
// https://github.com/algolia/autocomplete.js/issues/248 | ||
empty(query) { | ||
|
@@ -77,10 +104,17 @@ | |
} | ||
} | ||
})); | ||
autocomplete('#aa-search-input', autocompleteOptions, autocompleteSources) | ||
const $input = autocomplete('#aa-search-input', autocompleteOptions, autocompleteSources) | ||
.on('autocomplete:selected', (e, suggestion) => location.href = suggestion._href || suggestion.url); | ||
if (restoreFocus) $input.focus(); | ||
|
||
// Disable fallback form | ||
document.querySelector('#site-search-form').addEventListener('submit', (e) => e.preventDefault()); | ||
}); | ||
} | ||
|
||
// Lazyload | ||
document.querySelector('#aa-search-input').addEventListener('focus', setupSearch, { once: true }); | ||
document.querySelector('#site-search-form').addEventListener('click', setupSearch, { once: true }); | ||
// Preload | ||
window.addEventListener('load', () => setTimeout(setupSearch, 7000)); | ||
</script> |