最近有一个项目用到,jquery.autocomplete,本以为是一个之前项目组成员写的一个jquery插件,后来一搜索,不是内部原创,是引用一个广泛使用的公开插件。
       首先向作者致敬,作者解决了有无问题,本人侧重于结合项目做具体应用场景的性能优化。
       确认问题,上游反馈的用户体验糟糕的地方主要有两个,一个是搜索打开速度慢,一个是输入长关键词界面卡死现象。
       拿到代码,第一步确定性能瓶颈,粗略浏览代码,并没有发现一些恶名昭著的性能陷阱(复杂dom交互,大递归,大循环)初步确认可优化的项目有(标注为序号和蓝色)
              1、优化html模板系统,使用系统函数replace替代“+”
              2、合并html操作
              3、合并绑定事件
              4、使用[].join()代替+优化字符串操作
       代码引用形式为:
autoComplete({
                'target':'Dsearch',
                'input':'seachI',
                'container':'container',
                'url':'/search',
                'delay':100,
                'formatItem':function(item){
                        return '<span>'+item.name+'</span><em>'+item.count+'</em>';                }
,【1】优化html模板【                'formatItem':function(item,i){
                        return '<li i={$i$}><span>{$name$}</span><em>{$count$}</em></li>'.replace("{$name$}",item.name).replace("{$count$}",item.count).replace("{$i$}",i);
                },】

                'result':function(item){
                        window.location=item.url;
                },
                'callback':function(){                }
        });核心代码为:
var autoComplete=function(params){
        var $target=$("#"+params.target);
        var $input=$("#"+params.input);
        var $container=$("#"+params.container);
        $input.attr('autocomplete','off');
        var doAutocomplete=function(){
                var oldv=$input.val();
                var autoAC=function(){
                        if(oldv!=$input.val()){
                                var temp=$.ajax({type:'post',url:params.url,data:{'key':$input.val()},dataType:"text", 
                                        success: function(data){
                                           var json=eval("(" + data + ")");
                                                $container.html('');
                                                for(i=0;i<json.length;i++){
                                                        var $li=$("<li>"+params.formatItem(json)+"</li>");
                                                        $container.append($li);
                                                }
【2】合并dom操作【4】使用[].join()代替+
                                               【优化后为】
                                            var str_html=[];
                                                for(i=0;i<json.length;i++){
                                                        str_html.push(params.formatItem(json,i));
                                                }
                                                $container.html(str_html.join(''));

                                                $container.find('li').each(function(i){
                                                        $(this).unbind('click');
                                                        $(this).bind('click',function(){
                                                                params.result(json);
                                                        })
                                                });
【3合并事件绑定】
                                                【优化后为】
                                                var  mLi=$container.find('li');
                                                mLi.css("cursor","pointer");
                                                mLi.click(function(mEvent){
                                                            var i=mEvent.currentTarget.getAttribute("i");
                                                                params.result(json【i】);
                                                        });
                                                params.callback();
                                        } 
                                });
                        }
                        oldv=$input.val();
                        
                        setTimeout(function(){
                                autoAC();
                        },params.delay);
                }
                autoAC();
        };
        doAutocomplete();
}
之前在51js发布,可惜一周后还是待审核,只好换个地方发了。jquery.autocomplete性能优化js性能优化html模板