我在我的项目中使用jQueryUI's autcomplete。我有一个自动完成文本,其中用户搜索的东西和相应的数据下拉。
使用小数据集,它工作正常。当数据集很大时会出现问题。我有几乎1L记录具有唯一值,我作为autocomplete
的来源附加。
现在,只要用户在文本栏中输入搜索字符串,浏览器就会因为jQueryUI autocomplete
的处理而挂起原因。
我想知道如何优化它或使其更快,以便borwser不会挂起。这是我创建的plunkr。这就是我要将源附加到自动完成的过程。
$("#tags").autocomplete({
source: availableTags
});
答案 0 :(得分:6)
而不显示所有50000条记录仅显示前10条。最小搜索字符长度从默认0增加到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));
}
});
});
&#13;
<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>
&#13;
答案 1 :(得分:1)
添加显示结果的限制,例如十。
答案 2 :(得分:1)
<!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>
请检查
答案 3 :(得分:1)
我遇到了同样的问题,并通过使用自定义函数重写_renderMenu
函数来解决了该问题,该函数可以异步呈现项目列表。
首先,您定义一个异步渲染函数和一个用于停止异步渲染的函数(please read the API documentation,因此您知道自己在做什么):
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;
}
}
};
接下来,您将异步渲染功能分配给小部件:
$("#autocompleteId").data("ui-autocomplete")._renderMenu = customACFunctions.asyncRenderMenu;
接下来,当我们更改搜索查询时,我们还必须停止此异步呈现-我们的小部件不知道该异步呈现。 (否则,您的项目列表中会乱七八糟...)如果尚未为“搜索”事件定义事件处理程序,则可以执行以下操作:
$("#autocompleteId").on("autocompletesearch", customACFunctions.stopAsyncRendering);
如果您已为搜索事件定义了事件处理程序,那么请从该事件处理程序中调用此函数。
最好还是在用户选择一个项目时停止渲染。如果您已经为'select'事件定义了一个函数,则在事件处理程序中调用该函数。否则:
$("#autocompleteId").on("autocompleteselect", customACFunctions.stopAsyncRendering);
答案 4 :(得分:0)
我建议限制从本地设备以外的地方获取的数据。因为不显示它们并不意味着你没有为它们分配内存。虽然这样做也会有所帮助。 P.s:为我可怜的英语道歉