所在项目: 机票预定系统
所属模块: 前端查询模块
存在的问题: 用户查询出航班数据时,点击按照价格排序,当航班数据很多时(大于>30条),在IE浏览器下会因为消耗过多内存而崩溃
涉及的函数: 2个 reverseTr reverseTrLowToHigh
原来代码如下:
01 function reverseTr(sortType) {
02 var sortTrLength = $('.sortTable').length;
03 for (var sortedI = sortTrLength - 1; sortedI > 0; sortedI--) {
04 var minTr = $('.sortTable').eq(0);
05 var currentMin = 0;//定义当前最小值的编号用户与后面判断最终最小与最后是否相同,若同,则不变换位置(会引起删除现象)
06 for (var sortedJ = 0; sortedJ <= sortedI; sortedJ++) {
07 var sortingTr = $('.sortTable').eq(sortedJ);
08 if (parseInt(minTr.attr(sortType), '10') > parseInt(sortingTr.attr(sortType), '10')) {
09 minTr = sortingTr;
10 currentMin = sortedJ;
11 }
12 }
13 if (currentMin != sortedJ - 1) {
14 var currentLastTr = $('.sortTable').eq(sortedI);
15 currentLastTr.after(minTr);
16 }
17
18 }
19 var cssOdd = false;
20 $('.sortTable').each(function(){
21 if(cssOdd){
22 $(this).attr('class','odd sortTable');
23 cssOdd = false;
24 }else{
25 $(this).attr('class','sortTable');
26 cssOdd = true;
27 }
28
29 });
30 }
01 function reverseTrLowToHigh(sortType) {
02 var sortTrLength = $('.sortTable').length;
03
04 for (var sortedI = sortTrLength - 1; sortedI > 0; sortedI--) {
05 var minTr = $('.sortTable').eq(0);
06 var currentMin = 0;//定义当前最小值的编号用户与后面判断最终最小与最后是否相同,若同,则不变换位置(会引起删除现象)
07 for (var sortedJ = 0; sortedJ <= sortedI; sortedJ++) {
08 var sortingTr = $('.sortTable').eq(sortedJ);
09 if (parseInt(minTr.attr(sortType), '10') < parseInt(sortingTr.attr(sortType), '10')) {
10 minTr = sortingTr;
11 currentMin = sortedJ;
12 }
13 }
14 if (currentMin != sortedJ - 1) {
15 var currentLastTr = $('.sortTable').eq(sortedI);
16 currentLastTr.after(minTr);
17 }
18
19 }
20 var cssOdd = false;
21 $('.sortTable').each(function(){
22 if(cssOdd){
23 $(this).attr('class','odd sortTable');
24 cssOdd = false;
25 }else{
26 $(this).attr('class','sortTable');
27 cssOdd = true;
28 }
29
30 });
31 }
注:这两个JS函数可以根据传入的 sortType 排序,sortType不仅仅是价格;reverseTr 第 20 行,设置每一行的样式
根据页面的数据量来说,JS所采用的冒泡排序算法是没有问题的,那问题出在什么地方呢?
之前我并没有碰到过JS性能的问题,SO GOOGLE...... 发现 dom的绘制和重绘非常消耗CPU和内存,dom结构和样式发生变化时都会发生重绘,在IE下尤为突出(可能是因为IE没有做相关优化,chrome快的多)。
因此改正代码,减少重绘次数;
以这个函数 reverseTr 举例: 第 15 行, 之前每次操作都会去操作dom树,都会引起dom重绘;第 20 行,遍历航班列表 设置样式的操作,也会引起dom重绘;把dom操作进行合并,也就说现在内存中进行dom操作,然后apeend到当前dom树中,代码如下:
function reverseTr(sortType) {
var sortTrLength = $('.sortTable').length;
var temp = document.createElement("div");
temp.className = "tb-void";
for (var sortedI = sortTrLength - 1; sortedI > 0; sortedI--) {
var minTr = $('.sortTable').eq(0);
var currentMin = 0;//定义当前最小值的编号用户与后面判断最终最小与最后是否相同,若同,则不变换位置(会引起删除现象)
for (var sortedJ = 0; sortedJ <= sortedI; sortedJ++) {
var sortingTr = $('.sortTable').eq(sortedJ);
if (parseInt(minTr.attr(sortType), '10') > parseInt(sortingTr.attr(sortType), '10')) {
minTr = sortingTr;
currentMin = sortedJ;
}
}
if (currentMin != sortedJ - 1) {
var currentLastTr = $('.sortTable').eq(sortedI);
temp.appendChild(minTr.get(0));
}
}
$('.tb-void').empty();
var cssOdd = false;
var jtemp = $(temp);
jtemp.children().each(function(){
if(cssOdd){
$(this).attr('class','odd sortTable');
cssOdd = false;
}else{
$(this).attr('class','sortTable');
cssOdd = true;
}
});
$('.tb-void').replaceWith(jtemp);
}
很多知识参考了这篇文章:
https://www.ibm.com/developerworks/cn/web/1107_zhouxiang_tunejs/