We took a similar approach for our documentation search. [0]
You can see the "inverted index" is rendered inline in the page, since everything is generated at build time.
When you type something that matches a key in the index, we fetch that index key and add it to the results. [1] [2]
Obviously we could do a lot better in terms of relevancy, but it's simple and fast.
[0] https://docs.fastcomments.com/
[1] https://docs.fastcomments.com/index-ublJLBnXgz88.json
[2] https://github.com/FastComments/fastcomments-docs/blob/main/...
Relevancy is the huge game-changer. MDN uses pageviews analytics to determine was a "popular" age is.
Indeed, that's a great idea.
I remember doing something similar a few years ago, I needed autocomplete for a shipping ports field, the data was too big though so I ended up using a csv file in an aws lamda function that filters based on the selected country and returns a much smaller subset. It lazy loaded after the user selected the country. To keep response times low I had to do a binary search on the raw csv bytes. It felt like I was reinventing databases but I liked the idea of it being self contained in a function.
Have you looked into s3 select api, you can do sql against a flat file and return just the result all from s3, not too shabby to build a poor mans serverless database.
My favorite autocomplete library is an ancient version of bootstrap-typeahead.js by Twitter. A single file with less than 400 lines of Javascript. They don't make these anymore :)
I use it everywhere where I need autcompletion. For example on the Music-Map:
I made a fork of the code which is available here:
Getting accessibility right is hard. We very much care about that. One of the strong reasons for why we're using Downshift.
I did my first autocomplete search UI with that library.
These days, due to the rest of the project, I've been using Angular and Material's Autocomplete component, which I've found very easy to customise for in-memory indexes or hits to a remote ElasticSearch 'suggester' proxy endpoint.
It seems to be missing the most obvious feature: keyboard navigation. My guess is that accessibility is not well implemented either. Probably why other dropdown implementations are bigger code-size wise.
It has keyboard navigation. It is just not enabled on the Music-Map.
Gnoosic uses the same library, and here you can navigate with the cursor keys:
They hi-jacked the browser's `/` key to focus the field, which is something I hate. As a user, I want `/` to bring up Firefox's quick search bar, especially when reading documentation.
They should have just had the search field focused automatically but that would have done away with their "clever" hack to lazy-load the DB containing every page name.
Also, I'm confused, I thought https://mdn.dev/ was the new thing because Mozilla was stepping back from MDN. Is it a fork? They both carry Mozilla logos, so what's going on there?
Yeah discourse does the same. Sometimes i want to search within a post for some keyword. But ctrl+f redirects you to the global search... that global search only helps if you want to find interesting posts, but it does not support searching inside one, nor does it allow limited search within a thread. So I started using / in discourse discussions. Then that one was being overridden as well. I've heard the recommendation that you turn js off, which gives you a saner experience.
I hate this behaviour in discourse as well, but it hadn't occurred to me to try using it sans JS altogether, since it seemed to be pretty dependent on it. Will give that a shot for sure.
> But ctrl+f redirects you to the global search
Press ctrl-f twice.
Oh thanks for that trick. It violates the principle of least surprise so much but it does what I want. Thanks again!
I sometimes use Ctrl+G (Find Again) to get around sites hijacking / or Ctrl+F when I want to use the browserâs search functionality: if the current search doesnât match anything or if there is nothing to search for, then it opens the browserâs find bar. If that was hijacked too, you could still focus browser chrome (e.g. Ctrl+L, Ctrl+K, Alt+D and sometimes even others to focus the address/search bar) and then press Ctrl+F.
I knew the existence of "/", but never figure out why I should use this instead of Ctrl+F. What's the difference (other than have fewer features)?
This seems to be a good introduction to Quick Find.
https://www.tenforums.com/tutorials/120679-enable-disable-qu...
Ok, so the difference is:
1. It disappears after a few seconds.
2. It has no "next/previous/highlight all" etc. buttons (it still have these features, just no clickable buttons)
It still makes no sense to me.
I guess maybe a small portion of people would find the auto-disappearing thing useful, even though in normal Ctrl+F all you need to do is pressing Esc.
But the second "feature" totally baffles me. It's not like Ctrl+F is some expensive GUI to launch, why would I want to not have these buttons? Even if you don't need them at all (I don't), you can simply not click them, there is no downside by having them.
The only difference I know of is that "/" focuses links. So when you press return, it loads the link instead of jumping to the next result.
It's quite nice for keyboard-only web navigation.
> "/" focuses links.
It's ' to trigger quick find in links only mode.
Firefox lets you disable keyboard overrides on a per-site basis, if that's something you're interested in
Page Info -> Permissions -> Override Keyboard Shortcuts
> They hi-jacked the browser's `/` key to focus the field, which is something I hate.
You're not the first one to point it out. Please join github.com/mdn/yari to raise your voice. It's an Open Source project after all.
> They should have just had the search field focused automatically
Why? There's a lot of JS to load to make that work. If you never need to do a search (e.g. from a Google search) it would be a potential waste.
> Also, I'm confused, I thought https://mdn.dev/ was the new thing because Mozilla was stepping back from MDN. Is it a fork?
That domain is just an alias we don't currently use. It's still the old MDN from Mozilla. No fork.
> Why? There's a lot of JS to load to make that work. If you never need to do a search (e.g. from a Google search) it would be a potential waste.
Confused by what this comment is meant to say exactly, but just in case its not known already, seems this situation is what the autofocus attribute is for @ https://developer.mozilla.org/en-US/docs/Web/HTML/Global_att..., no JS needed
the op is saying "if we autofocussed, we'd need to load all the JS involved in performing the search"
Now I am curious if, in the real MDN production site, serach-index.json loading is triggered by the execution of /static/js/autocomplete.js, when their download should really be started in parallel by the shim.
Many websites leave a lot of performance on the table because of such behaviors.
My hypothesis is that, since this is easier for the developer, and works good enough, not many people really care. But these things add up, and the web becomes slower and slower.
MDN has 2 search things: 1. client-side only which downloads a complete list of all titles. 2. full-text search on everything with Elasticsearch.
First of all, great write up and interesting solution, thank you for that!
I think GPS question was rather whether the page loads the start autocomplete script on focus, and the script triggers download of the json data, as in the pseudo code, or whether the real code triggers downloading of both in parallel (the script and the json data)?
I like mosra's search, implemented in m.css for magnum. He wrote a blog post on it here: https://blog.magnum.graphics/meta/improved-doxygen-documenta... and you can try it on the magnum docs site: https://doc.magnum.graphics/magnum/#search
Fast and can be served from a static site.
Are they using react for just this one thing on this page!? Honestly it wasn't very clear to me, but they seemed to indicate that. I wonder if that's just because it's the pattern at MDN, but I feel like shipping react along with the JSON has got to be huge.
React's only 100kb (or ~30kb gzipped). You're not likely to notice that if it's fetched in the background.
100kb is a lot in the context of making one specific component work. If it's just one thing you could do it will far less overhead. Maybe preact or a native web component or something. If I'm not misunderstanding, then it does seem like how people would include jQuery just to select a few elements and change their classes or make an ajax call.
As an aside here... MDN docs are pretty awesome. I've been learning pure vanilla Javscript on this site more than anywhere else.
I used to automatically include jQuery in every project as a habit/reflex.
Now, because of MDN, I never do that anymore, unless It makes total sense. Kudos guys!
Get a daily email with the the top stories from Hacker News. No spam, unsubscribe at any time.