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