Javascript 在Safari上的jQuery都比Chrome/Firefox慢
我有一个大的HTML表格,1000-1500行,40列宽。我有一些输入框和选择框,用户可以过滤行。相关javascript/jquery注意:没有粘贴完整的代码库,因为它不是附加到它的瓶颈,如下所示:Javascript 在Safari上的jQuery都比Chrome/Firefox慢,javascript,jquery,html,Javascript,Jquery,Html,我有一个大的HTML表格,1000-1500行,40列宽。我有一些输入框和选择框,用户可以过滤行。相关javascript/jquery注意:没有粘贴完整的代码库,因为它不是附加到它的瓶颈,如下所示: function autoRank() { // auto number rank = 0; $("#myTablePlayers .playerData").each(function() { if ($(this).css("display") != "
function autoRank() {
// auto number
rank = 0;
$("#myTablePlayers .playerData").each(function() {
if ($(this).css("display") != "none") {
rank++;
$(this).find('td').eq(colRank).text(rank);
}
});
}
var teamCols = $(),
GPCols = $(),
posCols = $(),
ageCols = $();
$("#myTablePlayers .playerData").each(function() {
var columns = $(this).find('td');
teamCols = teamCols.add($(".colTeam", this));
GPCols = GPCols.add(columns.eq(colGP));
posCols = posCols.add(columns.eq(colPos));
ageCols = ageCols.add(columns.eq(colAge))
});
function filterTable() {
// Need some error checking on input not number
minGP = $("#mingp").val()
teams = $("#teamFilter").val().toUpperCase()
position = $("#position").val()
age = $("#age").val()
$("#myTablePlayers .playerData").show();
/* Loop through to check for teams */
if (teams) {
teamCols.each(function() {
if (!this.innerHTML.toUpperCase().includes(teams)) {
$(this).parent().hide();
}
});
}
/* Loop and check for min GP */
GPCols.each(function() {
if ( Number(this.innerHTML) < minGP) {
$(this).parent().hide();
}
});
/* Check for age requirement */
if (age) {
age = Number(age)
ageCols.each(function() {
thisAge = Number(this.innerHTML);
if ( thisAge < age || thisAge >= age+1 ) {
$(this).parent().hide();
}
});
}
/* Check the position requirement */
if (position) {
posCols.each(function() {
var thisPos = this.innerHTML
if (position == "D") {
if (thisPos.indexOf("D") == -1) {
$(this).parent().hide();
}
} else if (position == "F") {
if (thisPos.indexOf("D") != -1) {
$(this).parent().hide();
}
} else if (thisPos != position) {
$(this).parent().hide();
}
});
}
autoRank();
}
在filterTable函数中
当我在Chrome或Firefox上运行这个程序时,它会快速运行1秒钟,DOM会正确呈现。当我在Safari上执行时,需要30秒以上的时间
为什么会这样?我可以做些什么来适应这个浏览器
jQuery:1.11.1即使升级到3.1.1,也会出现相同的问题
狩猎:10.0.1
火狐:50
Chrome:54.0。删除代码中的所有重复和不必要的复杂性后,剩下的就是:
var colRank = 0, colTeam = 1, colGP = 2, colAge = 3, colPos = 4;
function filterTable() {
var minGP = +$("#mingp").val();
var age = +$("#age").val();
var teams = $("#teamFilter").val().toUpperCase();
var position = $("#position").val();
var rank = 0;
$("#myTablePlayers .playerData").each(function () {
if (
(teams && this.cells[colTeam].textContent.toUpperCase().includes(teams)) ||
(minGP && +this.cells[colGP].textContent < minGP) ||
(age && (+this.cells[colAge].textContent < age || +this.cells[colAge].textContent >= age+1)) ||
((position === "D" || position === "F") && this.cells[colPos].textContent.indexOf(position) === -1) ||
(!(position === "D" || position === "F") && (this.cells[colPos].textContent !== position))
) {
this.cells[colRank].textContent = ++rank;
this.style.display = "";
} else {
this.style.display = "none";
}
});
}
为了支持本地DOM操作,我已经删除了几乎所有的jQuery
剩下的。如果您想挤出最后一点可能的性能,可以将每个都调整到文档.getElementById'MyTablePlayer'.tBodies[0].行上的普通旧for循环中
按相似性对if条件重新排序:从通常过滤掉最多行的条件到过滤掉最少行的条件。由于JS存在短路情况,因此通过这种方式,可以全面检查较少的情况
使用渲染也可以提高渲染性能,但会牺牲灵活性
最后,您可以使用。这可能比手动设置表格单元格的内容快。自己测试。为什么不尝试使用原生JS循环?众所周知,jQuery.each都比原生for循环慢,也可能成为瓶颈,这是+1,用于使用vanilla JSO,它是如何指数的?请不要使用“指数”这个词,它甚至不是多项式。你知道你的代码有语法错误吗?colGP、colPos、colAge都是未定义的?你应该做的第一件事是将代码粘贴到其中并修复出现的所有错误。之后:正确地确定变量的范围。您到处都缺少var关键字。我同意用纯JS替换jQuery是加快执行速度的好方法。但大多数情况下,这是性能和代码简单性之间的折衷问题,因此只有在某些点已经被认为是关键点时,才可能对其进行搜索。在目前的情况下,情况有所不同:请记住,所有功能都可以在FF中快速工作,而问题只会在Safari中出现。所以我怀疑一个简单的通用优化能否解决这个问题。感谢@Tomalak的帮助和@cFreed对我之前的问题的回答。切换到Vanilla JS肯定会加快Safari的速度,在FF/Chrome上没有明显的区别。所以我的真实世界的问题得到了回答,但我很好奇为什么Safari和FF/Chrome上的速度要慢30倍,实际上是30秒+1秒。也许这是一个字符串比较。在Safari上设置display属性可能比较慢。可能代码本身在两种浏览器上都很快,但在其中一种浏览器上重新呈现表的速度很慢。有很多可能性。那么我必须承认,我之前的评论所揭示的想法是完全错误的。因此,我仍然非常困惑:像@ReilyBourne,我很想知道是什么造成了不同。正如他所说,除了解决他真正的单词问题之外,在Safari/jQuery这对组合中发现这个弱点对每个人来说都是非常有趣的。因为他掌握了这方面的所有要素,我建议ReilyBourne在Safari上发布另一个问题,现在已经明确了目标,比如寻找这两个版本之间性能差异的原因。你怎么看?出于学术兴趣,我也很好奇。我很确定这可以归结为Safari中一些已知的和记录在案的低效问题,但确定这一点需要我没有的资源——首先是Safari,但也需要足够的时间。
var colRank = 0, colTeam = 1, colGP = 2, colAge = 3, colPos = 4;
function filterTable() {
var minGP = +$("#mingp").val();
var age = +$("#age").val();
var teams = $("#teamFilter").val().toUpperCase();
var position = $("#position").val();
var rank = 0;
$("#myTablePlayers .playerData").each(function () {
if (
(teams && this.cells[colTeam].textContent.toUpperCase().includes(teams)) ||
(minGP && +this.cells[colGP].textContent < minGP) ||
(age && (+this.cells[colAge].textContent < age || +this.cells[colAge].textContent >= age+1)) ||
((position === "D" || position === "F") && this.cells[colPos].textContent.indexOf(position) === -1) ||
(!(position === "D" || position === "F") && (this.cells[colPos].textContent !== position))
) {
this.cells[colRank].textContent = ++rank;
this.style.display = "";
} else {
this.style.display = "none";
}
});
}