带有 LinQ 过滤器和 jQuery tmpl 示例的 jQuery AJAX 请求

Posted

技术标签:

【中文标题】带有 LinQ 过滤器和 jQuery tmpl 示例的 jQuery AJAX 请求【英文标题】:A jQuery AJAX request with LinQ filter and jQuery tmpl example 【发布时间】:2011-08-25 11:00:03 【问题描述】:

我们使用此脚本获取并过滤包含 100.000 个元素的 JSON,以便在用户端进行一些快速搜索,但不幸的是这还不够快。

你怎么看,我怎样才能让这个脚本运行得更快?

<script> 
    $(document).ready(function () 
        var data__ = new Array();
        var val__ = new Array();
        var val_sum = 0;


            $.ajax(
                url: 'hotel.php',
                type: 'POST',
                dataType: 'json',
                timeout: 5000,

                beforeSend: function () 

                , error: function (xhr, ajaxOptions, thrownError) 
                    alert(xhr.responseText);
                    alert(thrownError);
                    return false;
                ,

                success: function (data) 
                
                    var list = JSLINQ(data)
                       .Where(function(item) return item.regio == "Afrika"; )
                       .OrderBy(function(item)  return item.name; )
                       .Select(function(item) return item; );

                    var movies = list['items']

                    var markup = "<tr><td colspan='2'><b>Hotel: </b> $name</td><td><b>Régió:</b> $regio</td><td><b>Orszag:</b> $orszag</td><td><b>Város:</b> $varos</td></tr>";

                    /* Compile markup string as a named template */
                    $.template( "movieTemplate", markup );

                    /* Render the named template */
                    $( "#movieList" ).empty();
                    $.tmpl( "movieTemplate", movies ).appendTo( "#movieList" );
                
            );
            return false;
    );
</script> 

感谢您的帮助。

【问题讨论】:

哪一部分似乎很慢 - JSLINQ 查询或结果呈现或只是以 JSON 格式加载 100,000 条记录(结合起来会很慢)?顺便说一句,您显示多少搜索结果会很多吗? 【参考方案1】:

我将提出一些一般性的改进(第 1 项)和一些具体的(其余的)。你可以挑选你想去的那些。

    编译一次模板,而不是每次调用success。将它们移出success。 使用 underscoreJS 代替 JSLinq。 UnderscoreJS 尽可能将调用委托给本机浏览器实现,因此这是最大的性能改进。 如果可以,请使用 下划线模板 而不是 jQuery。它们比 jQuery 更快,也更灵活(因为它们是纯 JS,不像为你包装东西的 jQuery)。 注意:最近有一些关于其他模板引擎的讨论,但由于我没有使用它们,所以我不能多说。 如果下划线的语法困扰您,您可以轻松自定义它以使用 jQuery 语法(他们的文档中有一个示例),尽管您很快就会习惯它。

用下划线 JS 重写你的代码:

<script> 
        $(document).ready(function () 
            var data__ = [];
            var val__ = [];
            var val_sum = 0;
            var markup = "<% _.each(items, function(item)  %><tr><td colspan='2'><b>Hotel: </b> <%= item.name %></td><td><b>Régió:</b> <%= item.regio %></td><td><b>Orszag:</b> <%= item.orszag %></td><td><b>Város:</b> <%= item.varos %></td></tr><% ); %>";
            var compiledTemplate = _.template(markup);


                $.ajax(
                    url: 'hotel.php',
                    type: 'POST',
                    dataType: 'json',
                    timeout: 5000,

                    beforeSend: function () 

                    , error: function (xhr, ajaxOptions, thrownError) 
                        alert(xhr.responseText);
                        alert(thrownError);
                        return false;
                    ,

                    success: function (data) 
                    
                        var list = _(data)
                                         .chain()
                                         .select(data, function(item) return item.regio == "Afrika"; )
                                         .sortBy(function(item)  return item.name; )
                                         .value();

                        var movies = list['items']

                        /* Render the named template */
                        $( "#movieList" ).empty().append(compiledTemplate(movies));

                    
                );
                return false;
        );
    </script> 

最大的改进可以在最慢的浏览器——IE7 上看到。此代码应该比现有代码快 10 倍(大约),但请对它们进行分析以获得准确的数字。

【讨论】:

【参考方案2】:

您当然想应用 JSLinq 在服务器端执行的逻辑。

所以在服务器端只返回Name='Afrika' 的结果并按name 排序结果。这样您就没有 JSLinq 过滤和排序所有结果的开销。

这会产生。

通过网络发送的数据更少(作为过滤完成的服务器端) 无需订购(数据按正确顺序发送)

【讨论】:

我无法在服务器端过滤非洲 :( 这只是一个示例 JSlinq。我必须以抽象的方式制作,所以可以处理任何事情。即使我需要南美洲。 为什么你不能通过那个服务器端?在我看来,如果您有价值客户端,您可以将其与 ajax 调用一起发送。【参考方案3】:

我猜大部分时间都花在执行 LINQ 查询上。我建议您通过 javascript 分析器运行代码,例如 Google Chrome 中的 Profiles 来定位繁琐的操作。

另外,=== 有时可能比 == 更快,因为前者不执行类型转换,当您遍历更大的集合时,您可能会从中受益。同样使用分析器,看看使用原始 javascript 代码执行操作是否有任何好处:

var result = [];
for (var d in data)  // or regular for (var i = 0; ... 
    if (d.regio === "Afrika") 
        result.push(d); // or result[result.length] = d;
    


result.sort(function(a, b) 
    // sort a.name and b.name
);

我确实意识到这可以最大限度地减少 jQuery 核心的使用,但它是您至少检查库提供的开销(或优化)的一种方式。

还可以尝试在成熟的模板引擎上使用常规的字符串连接(或数组连接,具体取决于最适合您的方式)。

【讨论】:

【参考方案4】:

您要退回地区指示“非洲”的商品。请注意,“Afrika”的拼写可能是“Africa”,即使超时,您仍可能会收到很多物品。 在数据库中,确保表被正确索引,以使 where 和 orderby 尽可能快。

【讨论】:

我们使用 psql 作为数据库,所以它不能被取消索引。 Afrika 是 Afrika,因为该网站将是匈牙利语 :) 我们正确拼写 Afrika。

以上是关于带有 LinQ 过滤器和 jQuery tmpl 示例的 jQuery AJAX 请求的主要内容,如果未能解决你的问题,请参考以下文章

jquery模板jquery.tmpl.js使用教程(附jquery.tmpl.js下载)

jquery tmpl 详解

jQuery-tmpl 模板引擎使用方法说明

jQuery.tmpl

jQuery tmpl:如何呈现 Html?

Jquery.tmpl