perf(v2): load algolia JS only when user interacts with search (#2076)

* perf(v2): lazy load algolia JS when the user interacts with the search input

* useref
This commit is contained in:
Endi 2019-12-02 16:15:43 +07:00 committed by Yangshun Tay
parent 7a6516ce5d
commit cc2201e997

View file

@ -5,47 +5,48 @@
* LICENSE file in the root directory of this source tree.
*/
import React, {
useState,
useEffect,
useContext,
useRef,
useCallback,
} from 'react';
import React, {useRef, useCallback} from 'react';
import classnames from 'classnames';
import DocusaurusContext from '@docusaurus/context';
import useDocusaurusContext from '@docusaurus/useDocusaurusContext';
import './styles.css';
const loadJS = () => import('docsearch.js');
let loadedJs = false;
const Search = props => {
const [isEnabled, setIsEnabled] = useState(true);
const initialized = useRef(false);
const searchBarRef = useRef(null);
const context = useContext(DocusaurusContext);
const {siteConfig = {}} = useDocusaurusContext();
const {
themeConfig: {algolia},
} = siteConfig;
useEffect(() => {
const {siteConfig = {}} = context;
const {
themeConfig: {algolia},
} = siteConfig;
const initAlgolia = () => {
if (!initialized.current) {
window.docsearch({
appId: algolia.appId,
apiKey: algolia.apiKey,
indexName: algolia.indexName,
inputSelector: '#search_input_react',
algoliaOptions: algolia.algoliaOptions,
});
initialized.current = true;
}
};
// https://github.com/algolia/docsearch/issues/352
const isClient = typeof window !== 'undefined';
if (isClient) {
import('docsearch.js').then(({default: docsearch}) => {
docsearch({
appId: algolia.appId,
apiKey: algolia.apiKey,
indexName: algolia.indexName,
inputSelector: '#search_input_react',
algoliaOptions: algolia.algoliaOptions,
});
const loadAlgoliaJS = () => {
if (!loadedJs) {
loadJS().then(a => {
loadedJs = true;
window.docsearch = a.default;
initAlgolia();
});
} else {
console.warn('Search has failed to load and now is being disabled');
setIsEnabled(false);
initAlgolia();
}
}, []);
};
const toggleSearchIconClick = useCallback(
e => {
@ -58,7 +59,7 @@ const Search = props => {
[props.isSearchBarExpanded],
);
return isEnabled ? (
return (
<div className="navbar__search" key="search-box">
<span
aria-label="expand searchbar"
@ -80,12 +81,14 @@ const Search = props => {
{'search-bar-expanded': props.isSearchBarExpanded},
{'search-bar': !props.isSearchBarExpanded},
)}
onClick={loadAlgoliaJS}
onMouseOver={loadAlgoliaJS}
onFocus={toggleSearchIconClick}
onBlur={toggleSearchIconClick}
ref={searchBarRef}
/>
</div>
) : null;
);
};
export default Search;