I began my journey to speed up jQuery's autocomplete earlier this afternoon, and decided it was probably a good idea to begin memcaching everything. As suggested in this article: Speeding up autocomplete.
However, I am still dealing with slow response time even after installing and using Memcached.
The problem in my case is that I am dealing with extraordinarily long lists, in my case, over 6700 individual members. (All genera or genuses of all plants)
The bottleneck seems to be constructing the table and populating the client-side list, and it is not caused by retrieving the information from Memcached.
If anybody else has run into this particular problem, I would love to hear of a clever way to solve it. I will post my code below.
Note: This particular page is unavailable to the general public, and I am aware there are a few gaping security holes.
require_once 'oo/Database.php';
$mysqldb = new Database;
$memcache = new Memcache;
$memcache->connect('localhost', 11211) or die ("Could not connect to memcache");
$sql = "SELECT DISTINCT `Genus` FROM importlist.plants";
$key = md5('query'.$sql);
$result = $memcache->get($key);
//check if we got something back
if($result == null) {
//fetch from database
$result = $mysqldb->rawSelect($sql)->getResult();
//set to memcache, expires after 1 hour
$memcache->set($key,$result,0,3600);
}
//Result array
$Genera = ($memcache->get($key));
//Add required "quotation marks" for autocomplete
foreach ($Genera as &$Genus){
$Genus = '"'.$Genus[Genus].'"';
}
$Genera = implode($Genera,',');
//PHP to generate jQuery
echo <<< EOT
<script>
$(function() {
var availableTags = [$Genera];
$( "#tags" ).autocomplete({
source: availableTags
});
});
</script>
EOT;
?>
<input id="tags" />
$(document).ready(function() {
// once page loads, make AJAX request to get your autocomplete list and apply to HTML
$.ajax({ url: '/path-to-get-tags-as-json.php',
type: "GET",
contentType: "application/json",
success: function(tags) {
$( "#tags" ).autocomplete({
source: tags
});
}
});
});
Place the URL to your PHP file at generates the autocomplete list in the above AJAX placeholder url parameter. In your PHP code, modify the list generation so that it returns a JSON array of values like so:
[ "first" , "second" , "anotherEntry" , "in" , "the" , "array" ]
This will definitely not speed up the process server side, but it will protect your users from some of the delays in applying the autocomplete list. This largely assumes that the user doesn't instantly go perform an action that requires autocomplete, you can still load the page and allow the user to perform other actions. The loading of the autocomplete list should for the most part appear silent and seamless.
This is great for load times that are less than a few to several seconds, but if it's taking you longer than that then your users may still run into usability trouble.
If there are still server-side delays, consider using some timing statements to try and determine where the bottleneck is.
Since you can't lookup anything until the user types at least 1 character, you can create 26 different lists. Each autocomplete list only contains the items that begin with that letter. Your lists will be significantly smaller and faster to load.
To make it even faster, create more lists. You probably only need the first 30-40 items to display. If the item isn't in the shortened list, the user will very likely type another letter. You can then divide your lists up into 26*26 unique lists. Each list containing only items that begin with the first 2 letters.
You can divided your items up into as many lists as needed. We do this on a site I manage where we have over 500K items available in our typeahead.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With