By now you are already aware that at this point in time, this blog is using Hugo-PaperMod as its theme.
This theme, as I have repeatedly mentioned, is pretty minimalistic yet full of necessary features. One such feature is search. As this is a static website, search is implemented on the client-side.
When hugo builds the website, it generates a certain index.json
that is indexed for this very purpose. PaperMod uses Fuse.js for its search. You can read all about it in the GitHub hosted documentation.
This search implementation works alright for a blog with a few posts. Unfortunately, this blog is pretty old and has way too many posts.
Also the type-ahead search functionality in the theme is implemented in such a way that search is invoked on every keyup
event. This means that by the time you type a 5 letter word, the search function was invoked 5 times, even when it wasn’t really necessary! This creates a very sluggish experience for the user. This can be seen in the fastsearch.js
file in assets/js/
folder of the theme.
So I decided to do something about it, at least on my search page.
How do you start?
Most type-ahead implementations, at least back in the day where I used to write code, were done by keeping in mind that users need some time to type a keyword before the input should search for it. However, as I mentioned earlier, in PaperMod, the search input has an event listener on the keyup
event, which meant that every time a key is released, the search would get triggered. Very brute-force type of technique.
My solution was to add a sensible debounce
method to the search trigger. Debounce just a programming technique used to reduce unnecessary calls to a function.
I also chose to listen to the input
event instead of the keyup
event. I don’t care about old internet explorer users. As someone has taken the pain to explain the difference between the two on stackoverflow, I don’t want to repeat it here.
Explain the code
From line 5 to line 19, we define the debounce()
function that takes in a function, fn
and a delay
that defaults to 600
ms. This is vanilla javascript with no special library. We use setTimeout
to ensure the function is called after a certain delay. We also use clearTimeout
to reset the timeout if the function is invoked again.
from line 22 to line 50, we have the startSearch(e)
method that takes in the event. The key differences between this version and the version that comes with PaperMod:
- This one is a named function and not an anonymous arrow function
- References to
this
has been replaced with the actual qualifying object. E.g. On line 28, we refer tosInput.value.trim()
instead ofthis.value.trim()
- On line 53, we add an
input
EventListener
and define it to invokedebounce(startSearch, e)
Was it better?
Of course it was! That is exactly why I am blogging about it. Avoiding unnecessary calls to a function can do wonders for user experience. Type-ahead is the best use-case to demonstrate this. In my case, my browser doesn’t feel unresponsive when I type many characters at once into the search box and results don’t appear as duplicates any more.
I hope this was useful to you too.