javascript自动完成性能问题

时间:2014-08-12 09:33:11

标签: javascript performance autocomplete

我有一个使用javascript的自定义自动完成功能,它调用了keyup函数,该函数调用web服务来获取结果。它会生成结果,但是当我在字段中快速输入字符时,每个字符逐渐逐渐输入字符,因此UI上的最终感觉看起来非常慢。是否有任何可能的方法来设置输入延迟所以调用服务的ACCrequestSuggestions函数将在用户进入该字段时进行相当大的暂停时被调用。或者还有其他更好的方法来处理这个使用jvascript。请帮忙。

/**
* Handles keyup events.
*/
AutoSuggestControl.prototype.handleKeyUp = function (oEvent /*:Event*/) {
var iKeyCode = oEvent.keyCode;
//for backspace (8) and delete (46), shows suggestions without typeahead
if (iKeyCode == 8 || iKeyCode == 46) {
    ACCrequestSuggestions(this, false);

//make sure not to interfere with non-character keys
} else if (iKeyCode < 32 || (iKeyCode >= 33 && iKeyCode < 46) || (iKeyCode >= 112 && iKeyCode <= 123)) {
    //ignore
} else {
    //request suggestions from the suggestion provider with typeahead
ACCrequestSuggestions(this,true);
        }
};

/**
* Generate results and create the autocomplete drop down
*/

ACCrequestSuggestions = function (oAutoSuggestControl /*:AutoSuggestControl*/,
                    bTypeAhead /*:boolean*/) {

var aSuggestions = [];

// suggestions function will invoke service call to generate results based on input
aSuggestions = new Suggestions();

   //provide suggestions to the control by building div of results
oAutoSuggestControl.autosuggest(aSuggestions, bTypeAhead);
};

更新:

我按照建议使用了settimeout,效果很好。我打字时感觉更快。我的websetvice数据不是静态数据集。 Web服务根据我输入的字符进行搜索。所以我无法在客户端缓存数据。所以我无能为力。

var timeout; // scope global
if (timeout != "")
{
clearTimeout(timeout);
}
timeout = setTimeout(function(){
//Code to retrieve suggestions
},50);

2 个答案:

答案 0 :(得分:1)

您可以使用setTimeout()创建延迟,并在注册多次击键后只调用ACCrequestSuggestions一次:

AutoSuggestControl.prototype.handleKeyUp = (function() {
   var timer;
   return function (oEvent) {
     var that = this;
     try {
       clearTimeout(timer); //stop timeout on key up if it's already running
     } catch(ignore) {}
     //call your code with a given delay
     timer = setTimeout(function() {

       /***your original code***/
       var iKeyCode = oEvent.keyCode;
       //for backspace (8) and delete (46), shows suggestions without typeahead
       if (iKeyCode == 8 || iKeyCode == 46) {
         ACCrequestSuggestions(that, false);
       //make sure not to interfere with non-character keys
       } else if (iKeyCode < 32 || (iKeyCode >= 33 && iKeyCode < 46) || (iKeyCode >= 112 && iKeyCode <= 123)) {
         //ignore
       } else {
         //request suggestions from the suggestion provider with typeahead
         ACCrequestSuggestions(that,true);
       }

     }, 300); //300 ms should be nice for performance and also for user experience
   }
})();

当在小于300毫秒的距离内击中多个键时,请注意此版本仅在按下最后一个键时调用ACCrequestSuggestions。这可能会导致问题,但通常只会向用户显示一个结果,这当然应该是最后一次按键产生的结果。

答案 1 :(得分:0)

你在这里运行了很多代码,许多函数被调用,所有这些函数都可以运行多行代码。

开始的地方是添加一些逻辑并尝试编写代码。

如果可能的话,在做任何事情之前,首先等待2-3个字符条目,因为大多数单词至少需要2-3个字母。

二。使用setTimeout调用来包装执行所有工作的main函数调用,这将创建一个现在释放DOM / UI的线程情况。但它可能无法单独解决问题。

// tmr must have the scope to exist across all your methods

tmr = setTimeout(function(){ACCrequestSuggestions(this,true);},300)

正如我所示,每次键入一个键时,这将重置tmr。这将阻止所有代码运行,直到最后一次按键后300ms。

您可以在重置之前添加一个检查以查看是否已设置tmr,这将使autosuggest在键入时每300毫秒运行一次。

// for the purpose of the example we need a reference to our scope so we can
// use it in the function call below;

var self = this;
if (tmr) return
var tmr = setTimeout(function(){ACCrequestSuggestions(self,true);},300)

然后,当自动建议完成时,需要在代码中将tmr设置为undefined,允许在类型catch事件中触发新的tmr。

tmr=undefied;

我还会好好看看所有代码,并期待加快速度,如果网络服务很好,可以使用正确的策略让它看起来几乎是即时的。

更新:如何加快您的javascript速度!

Stack Overflow上有很多次我看到有关慢速代码的问题。在此示例中,OP正在寻求以用户类型的速度调用Web服务。从一开始就不会很好。

基础是用户输入一个角色时说&#34; A&#34;他打电话给网络服务器并对他的大数据进行一些API搜索,然后发回一大堆数据或一小部分数据。然后,当用户键入&#34; P&#34; - &GT; &#34; AP&#34;他重新做了这件事,尽管他已经掌握了最后一次电话的数据。

首先,当您搜索需要2-3个字母的东西时,要获得有意义的东西,这是第一个加快速度并减少负荷的地方。在2-3之后搜索,这也减少了服务器发回所有数据时的负载。

其次,一旦你在这个例子中找回了数据,我们就不需要再次调用服务器了。搜索可以在javascript中非常容易地完成,因为我们拥有来自A ---&gt;的结果的所有数据。向前。

这些技术可将您的应用/网站的性能提高10倍,并减少服务器的负载,更不用说您的用户和老板的体验了!