Optimising Ajax Search Suggestions
March 4, 2009 – 9:49 am
While i was watching Douglas Crockford’s talk on Ajax performance on the Yahoo developer network site yesterday, it occurred to me that the Ajax dropdown search suggestion list i wrote for a client’s site (mentioned in an earlier blog post) was rather inefficient in the way it handled the XMLHTTP requests.
When a user typed two characters into the search input box, my script would fire off an ajax request to the server and get a list of all matching strings from the relevant database field. If they typed a third character, it would do the same thing again for that string. And so on. I didn’t bother getting suggestions for just one typed character, as there would be too many suggestions for the user to handle easily and the extra load on the server and network seemed unnecessary.
However, i realised yesterday that there’s no point doing any requests after the first one – so long as the first two characters of the search string stay the same – because we’ve already got all the suggestions we need. After the first request, subsequent requests for longer search strings only return a subset of the results for the first two characters. So all i needed to do was to keep that first set of results and narrow it down as more characters were added to the string it needed to match.
The decision to reuse the old results or retrieve a new set depends on whether the first two characters of the search string match the first two characters of the first result of the old result set. If they match, then we’ve already got the results we need – if they don’t, then we do an XMLHTTP request and get some new results.
This change should result in quite a considerable saving in http request overheads and server load if users type more than two characters into the search box. It should also mean responsiveness improves noticeably – particularly on slow network connections.
While i was making these changes, i realised the way the search suggestions were being sent from the server could be optimised too. To keep things simple, i was retrieving the data from the mysql database, putting it into an array, and then json_encode’ing it and returning it to the browser, without doing any other processing. This seemed most efficient at the time. However, because mysql was returning an associative array with the field name as the key, the field name was included with every record – which was quite a lot of redundant data.
Looking at it a bit more critically, i realised there was no need to return the field name at all, as it was never used in the search suggestions code (it’s already known by the browser) – and having it there made the code more complicated anyway. I could have used a numeric array, rather than an associative one, but the key would still have been redundant. So i rewrote it to just push the value from the result into the array to be json_encoded.
On average, this ought to knock about a third off the data that needs to be sent in the XMLHTTPÂ request. It probably won’t make much difference over a fast network link, but it should be noticeable over a slow one.
This dropdown search suggestions system was my first Ajax project – and i was focussed more on getting it to work than on proper optimisation. Next time i’ll be thinking about optimisation from the outset.
Of course, while i was modifying my original code, i discovered a bug i hadn’t noticed before – so now i’m going to have to fix that too. Groan…
Hm, does your initial result set have a chance of being huge? Think X years down the line, will the AJAX be pulling thousands of results as soon as user hits two characters? You may want to just limit number of responses to say 10.
Of course this would mean you have to make another request for each letter. To combat this I occasionally use typewatch (http://www.dennydotnet.com/post/TypeWatch-jQuery-Plugin.aspx) or similar to fire ajax requests only when user has paused a bit. YMMV