docsearch icon indicating copy to clipboard operation
docsearch copied to clipboard

How can we consume a more performant modular set of docsearch?

Open TheLarkInn opened this issue 7 years ago • 4 comments

We are infinitely grateful at webpack that our docs are leveraging the DocSearch functionality with almost little to no needed effort on our side. So first off thank you.

Do you want to request a feature or report a bug? Kinda both? But not sure.

What is the current behavior? Currently when using docsearch.min.js and doing Code Coverage and Performance Analyses, we are identifying that docsearch.min.js script used to power the search on our webpack docs is shipping about 66% dead code on the initial download and render of the page. This means that for the default functionality, we only need about 40% of the actual code for webpack's doc experience to initially load.

For accessibility and web performance reasons, we are looking to only utilize the features we actually need, and even if possible, use import() to lazy-load additional pieces of functionality when events occur (such as, a user clicks the search field, then the modal appears, we don't need to modal js code, etc.).

  1. Is there a way to consume the docsearch code as raw source and not as a CDN, we very much would like to treeshake this code, but can't since it is not possible (unless I'm wrong) to pull the actual source and load it.

  2. Is there a way we can hoist interacting pieces of the docsearch functionality so that their modular pieces can be lazy-loaded on our terms?

An example. in fake React syntax.

import DocSearchMenuButton from "./DocSearchMenuButton";
import Loadable from "react-loadable";

const LazyLoadModalComponent = () => import("./DocSearchModal");

return (
  <DocSearchMenuButton with-modal={{ LazyLoadModalComponent }}>
)

This then allows the LazyLoadModalComponent to be called() on a DocSearchMenuButton event!!! Therefore, you never are placing import() inside your docsearch code, but for those projects looking to be as performant as possible, we can hoist this API to the top level and be handled the best possible way for first-class code-splitting.

The reason this struck my attention was that I noticed that @ulivz had to lazy load the entire bundle (maybe overkill with the right modular api's) for vuepress.

https://github.com/vuejs/vuepress/blob/f0b33e186a062f03469339a4839a1c8c01afc725/lib/default-theme/AlgoliaSearchBox.vue#L15-L18

Related screen shot 2018-04-27 at 11 35 33 pm

Thanks for all the support of our project and everything that your team does. If you want to reach out for more questions or a less crapy example, let me know!

~ Sean (webpack team)

TheLarkInn avatar Apr 28 '18 04:04 TheLarkInn

Hey Sean, thanks for taking a look at this. I think the main wins in this library are to do with the algoliasearch-helper module where its depends on a large chunk of lodash, without needing all of it, mostly because it used to be working for older browsers like IE8, and thus needed that consistency.

An option you can have to immediately make the load less of an impact is to do it like on the react site and load it on demand: source 1 and source 2.

I’m not exactly sure how to profile which bits of a UMD are used and where they come from, but I think also a significant amount can be learnt if the es module version of docsearch is used (maybe only for trying out things).

As far as I know, the build of the docsearch library is with webpack, so maybe you can also take a look there to see if there might be a way to have less code in the bundle.

If bundled, you can also resolve the es6-promise module to window.Promise, which will shave some size off the library.

Maybe another thing that can be done, but more longterm, is taking a look at algoliasearch/lite. I think some bits there aren’t necessary anymore (Parse client, not sure how it ended up in the build). The build process of that is quite outdated though (browserify), so might not be the fastest way to go.

I’ll have you know that decreasing code size all along the stack is a priority for us for this year.

EDIT: I just realised that docsearch doesn’t use the helper, so changes there won’t have an impact here

Haroenv avatar Apr 28 '18 08:04 Haroenv

The modular way of importing will be done via import ... from ‘docsearch.js/dist/npm...’

see https://yarnpkg.com/en/package/docsearch.js?files

Haroenv avatar Apr 28 '18 08:04 Haroenv

FYI we're currently thinking about a v3 of DocSearch that might drop the previous dependency on autocomplete.js (itself depending on zepto.js). Instead, we might use the core of our other front-end library, InstantSearch.js, were code is already importable by only the needed chunks.

Until this is released (and we have no ETA for that right now), the only solutions I see would be to import part of the library from the dist/npm directory like @Haroenv is mentionning. Hope that helps.

When the time will come for us to actually start this v3 development, we'll make sure to address all your concerns and might even ask for feedback on the best way to help users only use what they need :)

pixelastic avatar Aug 20 '18 13:08 pixelastic

Will be doable thanks to the v3 (in beta so far)

s-pace avatar Sep 03 '19 07:09 s-pace