这个问题不是寻找特定问题的解决方案,而是试图理解为什么Safari在这种情况下效率低下。当我谈论速度极慢时,代码在Firefox和Chrome中以不到1秒的速度运行,而Safari则在30-90秒的范围内运行。它可能已经是一个记录在案的问题,但我不知道为什么。
情况是我有一个相当大的HTML表。它的行数为1,000-1,500行,40列宽。结构看起来像:
<table id="myTablePlayers" class="tablesorter table table-striped table-bordered table-hover" style="overflow: visible">
<thead>
<tr>
<th>...</th>
<th>...</th>
<th>...</th>
<th>...</th>
...
<th>...</th>
</tr>
</thead>
<tbody>
<tr class="playerData">
<td>...</td>
<td>...</td>
<td>...</td>
<td>...</td>
...
<td>...</td>
</tr>
...
</tbody>
</table>
许多表单字段允许用户选择并输入有助于过滤掉行的信息。 jQuery看起来像:
function autoRank() {
// auto number
rank = 0;
$("#myTablePlayers .playerData").each(function() {
if ($(this).css("display") != "none") {
rank++;
$(this).find('td').eq(colRank).text(rank);
}
});
}
function filterTable() {
// Need some error checking on input not number
minGP = $("#mingp").val()
teams = $("#teamFilter").val()
position = $("#position").val()
age = $("#age").val()
$("#myTablePlayers .playerData").show();
$("#myTablePlayers .playerData").each(function() {
toHide = false;
if (teams != "") {
if ( !$(this).find('td').eq(colTeam).text().toUpperCase().includes(teams.toUpperCase())) {
toHide = true;
}
}
if ( Number($(this).find('td').eq(colGP).text()) < minGP ) {
toHide = true;
}
if (position != "") {
if (position == "D") {
if ($(this).find('td').eq(colPos).text().indexOf("D") == -1) {
toHide = true;
}
} else if (position == "F") {
if ($(this).find('td').eq(colPos).text().indexOf("D") != -1) {
toHide = true;
}
} else if ( $(this).find('td').eq(colPos).text() != position) {
toHide = true;
}
}
if (age != "") {
column = Number($(this).find('td').eq(colAge).text())
age = Number(age)
if ( column < age || column >= age+1 ) {
toHide = true;
}
}
if (toHide == true) {
$(this).hide();
}
});
autoRank();
}
$("#teamFilter").on('change', filterTable);
$("#mingp").on('change', filterTable);
$("#position").on('change', filterTable);
$("#age").on('change', filterTable);
当我开始修剪代码时,无论循环内部是什么,需要很长时间才能运行的违规代码似乎是$("#myTablePlayers .playerData").each(function() {...
我通过在vanilla JS中重写代码解决了这个问题,但是这并没有解释为什么这个代码只在一个浏览器中效率低下。
答案 0 :(得分:5)
通过.css()
进行查询来检查DOM状态可能非常昂贵。
不要使用.hide()
和.show()
隐藏/显示元素,而是添加/删除类。在你的CSS中:
.hidden { display: none; }
然后你的.each()
循环可以检查该类:
$("#myTablePlayers .playerData").each(function() {
if (!$(this).hasClass("hidden")) {
rank++;
$(this).find('td').eq(colRank).text(rank);
}
});
要隐藏某些内容,您只需添加该类,并显示它即可将其删除:
if (toHide) {
$(this).addClass("hidden");
}
并表示:
$("#myTablePlayers .playerData").removeClass("hidden");
现在,所有这些.find()
和.text()
来电也都很昂贵。通过遍历它并在每个<tr>
上创建数据属性来初始化表可能是值得的,以有效地缓存每行中的有趣值。通过jQuery的.data()
进行查找比使用DOM中的选择器要便宜得多(尽管现代DOM实现速度非常快)。