I am using jQueryUI's autcomplete in my project. I have a autocomplete text where user search something and corresponding data comes in drop down.
With a small data set, it's working fine. The problem arises when the data set is large. I have almost 1L records with unique values which I've attach as source to autocomplete
.
Now as soon as user enter search string in the text bar the browser hangs cause because of the processing that autocomplete
of jQueryUI does.
I want to know how can I optimize it or make it faster so that the borwser does not hang. Here's the plunkr I have created to play. And this is what I am doing to attach source to autocomplete.
$("#tags").autocomplete({
source: availableTags
});
I am using jQueryUI's autcomplete in my project. I have a autocomplete text where user search something and corresponding data comes in drop down.
With a small data set, it's working fine. The problem arises when the data set is large. I have almost 1L records with unique values which I've attach as source to autocomplete
.
Now as soon as user enter search string in the text bar the browser hangs cause because of the processing that autocomplete
of jQueryUI does.
I want to know how can I optimize it or make it faster so that the borwser does not hang. Here's the plunkr I have created to play. And this is what I am doing to attach source to autocomplete.
$("#tags").autocomplete({
source: availableTags
});
Share
Improve this question
edited Jan 23, 2018 at 8:42
marc_s
755k184 gold badges1.4k silver badges1.5k bronze badges
asked Aug 17, 2016 at 7:12
Hitesh KumarHitesh Kumar
3,6989 gold badges48 silver badges73 bronze badges
0
6 Answers
Reset to default 11Instead of show all 50000 records show only top 10. Minimum search character length increased from default 0 to 2
$(function () {
var availableTags = [
"ActionScript",
"AppleScript",
"Asp",
"BASIC",
"C",
"C++",
"Clojure",
"COBOL",
"ColdFusion",
"Erlang",
"Fortran",
"Groovy",
"Haskell",
"Java",
"JavaScript",
"Lisp",
"Perl",
"PHP",
"Python",
"Ruby",
"Scala",
"Scheme"
];
for (var i = 0; i < 50000; i++) {
availableTags.push('abc' + i);
}
$("#tags").autocomplete({
minLength: 2,
source: function (request, response) {
var results = $.ui.autocomplete.filter(availableTags, request.term);
response(results.slice(0, 10));
}
});
});
<link rel="stylesheet" href="//code.jquery.com/ui/1.12.0/themes/base/jquery-ui.css">
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script src="https://code.jquery.com/ui/1.12.0/jquery-ui.js"></script>
<div class="ui-widget">
<label for="tags">Tags: </label>
<input id="tags">
</div>
Add a limit of displayed results, like ten.
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>jQuery UI Autocomplete - Default functionality</title>
<link rel="stylesheet" href="//code.jquery.com/ui/1.12.0/themes/base/jquery-ui.css">
<link rel="stylesheet" href="/resources/demos/style.css">
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script src="https://code.jquery.com/ui/1.12.0/jquery-ui.js"></script>
<script>
$( function() {
var availableTags = [
"ActionScript",
"AppleScript",
"Asp",
"BASIC",
"C",
"C++",
"Clojure",
"COBOL",
"ColdFusion",
"Erlang",
"Fortran",
"Groovy",
"Haskell",
"Java",
"JavaScript",
"Lisp",
"Perl",
"PHP",
"Python",
"Ruby",
"Scala",
"Scheme"
];
var max= 10000;
// change max to 1000000 ie. 1L and it hangs.
for(var i=0;i<max;i++){
availableTags.push(i+'');
}
$("#tags").autocomplete({
source: function(request, response) {
var results = $.ui.autocomplete.filter(availableTags, request.term);
response(results.slice(0, 20));
}
});
} );
</script>
</head>
<body>
<div class="ui-widget">
<label for="tags">Tags: </label>
<input id="tags">
</div>
</body>
</html>
Please check this
I faced the same issue and solved the issue by overriding the _renderMenu
function with a custom function that renders the itemlist asynchronously.
First you define an asynchronous rendering function AND a function to stop the asynchronous rendering (please read the API documentation, so you know what you are doing):
let customACFunctions = {
asyncRenderMenu: function(ul, data) {
let batchSize = 20;
let autoc = this; //refers to the autocomplete widget.
function renderNextBatch(){
$(ul).find('li.autocomplete-spinner').remove();
let j = 0;
while (j < batchSize && data.length > 0) {
autoc._renderItemData(ul, data.shift());
j++;
}
//normally, the widget internals add this class to each list item, now
//we'll have to do it ourselves
$(ul).find('li:not(.ui-menu-item)').addClass('ui-menu-item');
if (data.length > 0) {
//add an 'item' to indicate that the list is still being 'loaded'
$(ul).append('<li class="ui-menu-item autocomplete-spinner"><a>Laden...</a></li>');
customACFunctions._asyncRenderingTimeoutId = setTimeout(renderNextBatch, 1);
}
}
renderNextBatch();
},
_asyncRenderingTimeoutId: null,
stopAsyncRendering: function() {
if (customACFunctions._asyncRenderingTimeoutId) {
clearTimeout(customACFunctions._asyncRenderingTimeoutId);
customACFunctions._asyncRenderingTimeoutId = null;
}
}
};
Next, you will assign the asynchronous rendering function to the widget:
$("#autocompleteId").data("ui-autocomplete")._renderMenu = customACFunctions.asyncRenderMenu;
Next, we will also have to stop this asynchronous rendering - of which our widget is unaware - when we change the search query. (Otherwise you will get a mess in your item list...) If you have not defined an event handler for the 'search' event, you can do:
$("#autocompleteId").on("autocompletesearch", customACFunctions.stopAsyncRendering);
If you have defined an event handler for the search event, than invoke this function from that event handler.
And best is also to stop rendering when the user selects an item. If you have defined a function for the 'select' event, then invoke this function in your event handler. Otherwise:
$("#autocompleteId").on("autocompleteselect", customACFunctions.stopAsyncRendering);
I recommend to limit the data you fetch from somewhere other than local device.cause not displaying them does not mean you have not allotted memory for them. although doing so would help also. P.s : apology for my poor english
Due to large volume of data set, some time this issue occurs. Browser get hang while loading large amount of data,
Here, first filter will work to slice a array and will return the decided accurate values from the whole data.
$("#postcode").autocomplete({
source: function (request, response){
var results = $.ui.autocomplete.filter(your_array,request.term);
response(results.slice(0, 10));
}
});
hope this will works for you