Javascript 为什么这个jQuery代码比这个慢得多?

Javascript 为什么这个jQuery代码比这个慢得多?,javascript,jquery,Javascript,Jquery,我有两个类似div的列,每个列都有不同内容的内部div,如下所示: (我将“内部div”称为“line”) 第1列第1行的文本是第2列第1行的翻译, 第1列第2行的文本是第2列第2行的翻译, 第1列第3行的文本是第2列第3行的翻译, 等等。 我需要实现的是: 第1列第1行应与第2列第1行对齐, 第1列第2行应与第2列第2行对齐, 第1列第3行应与第2列第3行对齐, 等等 因此,与此相反: 我希望是这样 我用这个代码实现了这一点 var t0 = performance.now(); v

我有两个类似div的列,每个列都有不同内容的内部div,如下所示:

(我将“内部div”称为“line”)

第1列第1行的文本是第2列第1行的翻译,
第1列第2行的文本是第2列第2行的翻译,
第1列第3行的文本是第2列第3行的翻译,
等等。
我需要实现的是:
第1列第1行应与第2列第1行对齐,
第1列第2行应与第2列第2行对齐,
第1列第3行应与第2列第3行对齐,
等等

因此,与此相反: 我希望是这样

我用这个代码实现了这一点

  var t0 = performance.now();
  var leftArray = $('#left .line').map(function(i) {
    return $(this).height();
  });
  var rightArray = $('#right .line').map(function(i) {
    return $(this).height();
  });
  for (var i = 0; i < leftArray.length; i++) {
    if (leftArray[i] < rightArray[i]) {
     $('#left .line').eq(i).css('height', rightArray[i])
    } else if (leftArray[i] > rightArray[i]) {
     $('#right .line').eq(i).css('height', leftArray[i])
   }
 }
但是,当我在2列上执行此函数时,每列有3oo行,它将接管(2000ms)

因此,我更改了代码,改为使用
.reduce
,这允许我保存具有最大高度的行索引,以便在设置元素(其他行)的最大高度时可以忽略它

这是我使用的代码

        //number of lines/column
        var column_lines_count =$('.lines').get(0).childElementCount

        var target,realArray,maxHeight,index_max_height,next_h=0;
        for (var i = 1; i < column_lines_count; i++) {

         //get lines with the same index from each column
         target = $('[data-row="'+i+'"]');

         //Convert to array so we can use reduce
         realArray =  $.makeArray( target );

         //variable to save the index of the line that has the maximum height, so we don't have to set the height for it. 
         index_max_height=0

           /*
           * Reduce=>
           * intial value => $(realArray[0]).height()
           * next is represents the line
           * index = index of that line
            */  
           maxHeight = realArray.reduce(function(biggerHeight, next,index) {
             next_h = $(next).height();
             if(biggerHeight > next_h){
               return biggerHeight;
             } else{
               index_max_height =index;
               return next_h; 
             }
           }, $(realArray[0]).height());        

       /*
        *for elements (lines) that has index != index of max_height line - set the max height
        *
        */
        $.map( target, function( a, index ) {
            if(index != index_max_height){
              $(a).css('height', maxHeight);    
          }
        });

     }  

根据@DanielBeck的建议

在数组中预先计算这些高度,而不是每次都从DOM中读取它们

解决问题,
这是比第一个代码更快的新代码

 var number_of_columns = $('.lines').length;

 var lines = $('.line');
 var column_lines_count =lines.length/number_of_columns;
 var leftArray = lines.map(function(i) {
     return $(this).height();
 }); 
 var realArray,maxHeight;

 for (var i = 1; i < column_lines_count; i++) {
      var corresponding_lines = [];
      var mindex;
      for(var j=0; j < number_of_columns; j++){
          mindex = i-1+(j*column_lines_count);
           corresponding_lines.push(leftArray[mindex]);
     }

    //Convert to array so we can use reduce
     realArray =  $.makeArray( corresponding_lines );


   maxHeight = realArray.reduce(function(biggerHeight, next,index) {   
      if(biggerHeight > next){
        return biggerHeight;
      } else{
        return next; 
      }
    }, realArray[0]);       

    $('[data-row="'+i+'"]').css('height', maxHeight);   
  }
var number\u of_columns=$('.lines')。长度;
变量行=$('.line');
var column\u lines\u count=行数。长度/列数;
var leftArray=lines.map(函数(i){
返回$(this.height();
}); 
var realArray,maxHeight;
对于(变量i=1;inext){
返回较大高度;
}否则{
下一步返回;
}
},realArray[0]);
$(“[data row=“”+i+“]”)css('height',maxHeight);
}

如@DanielBeck所建议

在数组中预先计算这些高度,而不是每次都从DOM中读取它们

解决问题,
这是比第一个代码更快的新代码

 var number_of_columns = $('.lines').length;

 var lines = $('.line');
 var column_lines_count =lines.length/number_of_columns;
 var leftArray = lines.map(function(i) {
     return $(this).height();
 }); 
 var realArray,maxHeight;

 for (var i = 1; i < column_lines_count; i++) {
      var corresponding_lines = [];
      var mindex;
      for(var j=0; j < number_of_columns; j++){
          mindex = i-1+(j*column_lines_count);
           corresponding_lines.push(leftArray[mindex]);
     }

    //Convert to array so we can use reduce
     realArray =  $.makeArray( corresponding_lines );


   maxHeight = realArray.reduce(function(biggerHeight, next,index) {   
      if(biggerHeight > next){
        return biggerHeight;
      } else{
        return next; 
      }
    }, realArray[0]);       

    $('[data-row="'+i+'"]').css('height', maxHeight);   
  }
var number\u of_columns=$('.lines')。长度;
变量行=$('.line');
var column\u lines\u count=行数。长度/列数;
var leftArray=lines.map(函数(i){
返回$(this.height();
}); 
var realArray,maxHeight;
对于(变量i=1;inext){
返回较大高度;
}否则{
下一步返回;
}
},realArray[0]);
$(“[data row=“”+i+“]”)css('height',maxHeight);
}

免费大幅提升性能:尽可能从缓存jQuery对象开始。将它们存储在变量中并重用它们。例如,而不是
$(“a”).func1()$(“a”).func2()$(“a”).func3()
只需访问DOM一次:
var$a=$(“a”)
并重用它:
a.func1()$a、 func2()$a、 func3()选择是昂贵的,您的第二和第三个代码比原始代码使用更多的搜索,原始代码使用2个选择器并映射数据directly@Icepickle谢谢你的评论,这很有帮助,所以我更新了代码,在循环外使用了一个主选择器,但速度仍然很慢,我用新代码更新了问题,如果您能看一看并给我更多建议,我将不胜感激。您仍在使用
$(next).height()在循环中进行DOM搜索。(实际上,在嵌套循环中,因为它位于
reduce
函数中)。在数组中预先计算这些高度,而不是每次都从DOM中读取它们。虽然在这种情况下,我建议扔掉所有这些代码并使用一个
,它会自动完成所有布局。。。您将失去单独滚动每个列的能力,但我不确定在这种情况下滚动单个列的目的是什么,因为您正在调整内容以允许跨列进行比较。免费大规模性能提升:尽可能从缓存jQuery对象开始。将它们存储在变量中并重用它们。例如,而不是
$(“a”).func1()$(“a”).func2()$(“a”).func3()
只需访问DOM一次:
var$a=$(“a”)
并重用它:
a.func1()$a、 func2()$a、 func3()选择是昂贵的,您的第二和第三个代码比原始代码使用更多的搜索,原始代码使用2个选择器并映射数据directly@Icepickle谢谢你的评论,这很有帮助,所以我更新了代码,在循环外使用了一个主选择器,但速度仍然很慢,我用新代码更新了问题,如果您能看一看并给我更多建议,我将不胜感激。您仍在使用
$(next).height()在循环中进行DOM搜索。(实际上,在嵌套循环中,因为它位于
reduce
函数中)。在数组中预先计算这些高度,而不是每次都从DOM中读取它们。虽然在这种情况下,我建议扔掉所有这些代码并使用一个
,它会自动完成所有布局。。。您将失去单独滚动每个列的能力,但我不确定在这种情况下滚动单个列的目的是什么,因为您正在调整内容以允许跨列进行比较
 var number_of_columns = $('.lines').length;

 var lines = $('.line');
 var column_lines_count =lines.length/number_of_columns;
 var leftArray = lines.map(function(i) {
     return $(this).height();
 }); 
 var realArray,maxHeight;

 for (var i = 1; i < column_lines_count; i++) {
      var corresponding_lines = [];
      var mindex;
      for(var j=0; j < number_of_columns; j++){
          mindex = i-1+(j*column_lines_count);
           corresponding_lines.push(leftArray[mindex]);
     }

    //Convert to array so we can use reduce
     realArray =  $.makeArray( corresponding_lines );


   maxHeight = realArray.reduce(function(biggerHeight, next,index) {   
      if(biggerHeight > next){
        return biggerHeight;
      } else{
        return next; 
      }
    }, realArray[0]);       

    $('[data-row="'+i+'"]').css('height', maxHeight);   
  }