为什么这个 Javascript 比它的 jQuery 等价物“慢”得多?
我有一个大约 500 个项目的 HTML 列表,上面有一个“过滤器”框。我开始在输入字母时使用 jQuery 来过滤列表(稍后添加计时代码):
$('#filter').keyup( function() {
var jqStart = (new Date).getTime();
var search = $(this).val().toLowerCase();
var $list = $('ul.ablist > li');
$list.each( function() {
if ( $(this).text().toLowerCase().indexOf(search) === -1 )
$(this).hide();
else
$(this).show();
} );
console.log('Time: ' + ((new Date).getTime() - jqStart));
} );
但是,输入每个字母(特别是第一个字母)后有几秒钟的延迟。所以我想如果我使用普通的 Javascript 可能会稍微快一些(我最近读到 jQuery 的 each
函数特别慢)。这是我的 JS 等效项:
document.getElementById('filter').addEventListener( 'keyup', function () {
var jsStart = (new Date).getTime();
var search = this.value.toLowerCase();
var list = document.querySelectorAll('ul.ablist > li');
for ( var i = 0; i < list.length; i++ )
{
if ( list[i].innerText.toLowerCase().indexOf(search) === -1 )
list[i].style.display = 'none';
else
list[i].style.display = 'block';
}
console.log('Time: ' + ((new Date).getTime() - jsStart));
}, false );
然而,令我惊讶的是,普通 Javascript 比 jQuery 等效项慢 10 倍。 jQuery 版本大约需要 2-3 秒来过滤每个字母,而 Javascript 版本需要 17 秒以上!我在 Ubuntu Linux 上使用 Google Chrome。
这并不是真正重要的事情,因此不需要非常高效。但我在这里用 Javascript 做了一些非常愚蠢的事情吗?
I have a HTML list of about 500 items and a "filter" box above it. I started by using jQuery to filter the list when I typed a letter (timing code added later):
$('#filter').keyup( function() {
var jqStart = (new Date).getTime();
var search = $(this).val().toLowerCase();
var $list = $('ul.ablist > li');
$list.each( function() {
if ( $(this).text().toLowerCase().indexOf(search) === -1 )
$(this).hide();
else
$(this).show();
} );
console.log('Time: ' + ((new Date).getTime() - jqStart));
} );
However, there was a couple of seconds delay after typing each letter (particularly the first letter). So I thought it may be slightly quicker if I used plain Javascript (I read recently that jQuery's each
function is particularly slow). Here's my JS equivalent:
document.getElementById('filter').addEventListener( 'keyup', function () {
var jsStart = (new Date).getTime();
var search = this.value.toLowerCase();
var list = document.querySelectorAll('ul.ablist > li');
for ( var i = 0; i < list.length; i++ )
{
if ( list[i].innerText.toLowerCase().indexOf(search) === -1 )
list[i].style.display = 'none';
else
list[i].style.display = 'block';
}
console.log('Time: ' + ((new Date).getTime() - jsStart));
}, false );
To my surprise however, the plain Javascript is up to 10 times slower than the jQuery equivalent. The jQuery version takes around 2-3 seconds to filter on each letter, while the Javascript version takes 17+ seconds! I'm using Google Chrome on Ubuntu Linux.
This isn't for anything really important so it doesn't need to be super efficient. But am I doing something really dumb with my Javascript here?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
您可以尝试使用
textContent
而不是innerText
,我认为它应该更快。另外,分别对列表生成和循环进行计时可以判断列表生成是否存在问题。You could try using
textContent
instead ofinnerText
, I think it should be faster. Also timing the list-generation and loop separately would tell if there is problem in list-generation.提高 JavaScript 速度的另一个最佳实践是将
list.length
缓存在变量中并调用该变量,如下所示:也许可以使用
Another best practice for javascript speed is caching the
list.length
in a variable and calling the variable like:And maybe timing with jsperf would be better.
在这里,我对您的代码进行了一些重构:
现场演示: http://jsfiddle.net /MVFxn/
更改:
toLowerCase
i
标志,如果只有一个'.ablist'
元素在页面上,querySelector
应该是获取它的最快方法(因为一旦找到第一个这样的元素,它就会中止查询),children
以来,没有对 LI 元素的查询code> 属性已经方便地引用它们。我很想知道这段代码在您的页面上的执行情况...
Here, I've refactored your code a bit:
Live demo: http://jsfiddle.net/MVFxn/
Changes:
i
flag, there's no need fortoLowerCase
,'.ablist'
element on the page,querySelector
should be the fastest way to grab it (since it aborts the query once it finds the first such element),children
property already references them conveniently.I'd love to know how this code performs on your page...
我使用
while
而不是for
并做了一些小的改进。 这里是最终代码。I used
while
instead offor
and did some minor improvements. Here is the final code.