带有 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 请求的主要内容,如果未能解决你的问题,请参考以下文章