for循环中的display:none及其对reflow的影响

时间:2016-05-28 01:22:44

标签: javascript css reflow

我今天正在阅读一些代码并遇到了这个for循环:

$cl=$dbh->prepare("SELECT id2 FROM users WHERE id = :id");
  $cl->bindParam(':id', $id);
  $cl->execute();
  $cli=$cl->fetch(PDO::FETCH_ASSOC);
  $lid=$cli['id2'];
  if($id !== $id2) {
    exit("mismatch error");
  }
}

我才开始了解浏览器重排;但是,我目前的理解是,这个循环正在为它设置的100个元素中的每个元素引起重排。显示无。

这个循环对DOM有什么影响?这真的像我想的那样可怕吗?

在翻新新页面时使用此代码。

2 个答案:

答案 0 :(得分:3)

Chrome Developer Tools时间轴是测试这类问题的一种很好的方法,特别是因为我认为它是可怕的#34;是相当主观的。

我对您在此fiddle中发布的代码进行了测试。称之为测试1

  • 请注意,我使用了1000个元素而不是100个元素进行测试。

对于控件,我使用 this fiddle中的代码,通过在动画帧中将包装元素设置为display:'none'来有效地隐藏元素。称之为测试2

  • 测试1 中,渲染 17.6毫秒
  • 测试2 中,渲染耗时 1.5毫秒

所以经验答案是肯定的,测试代码需要超过10倍的计算时间来重排页面布局,而不是替代(理想)方法。如果不了解提取它的代码的更多信息,很难说使用的方法是否合适或必要。

例如,如果要隐藏的元素没有整齐地包装在自己的包装器<div>中,则优化很困难。避免for循环的策略是分配元素a&#34; hideable&#34;类,并设置像wrapper.hideChildren > .hideable { display:none; }这样的CSS规则。然后,当我们分配课程&#34; hideChildren&#34;对于包装器,标记的元素是隐藏的。 Using this strategy,当操作之前将包装器从DOM中分离并重新连接时,我只能将渲染时间缩短到 15ms 10ms 然后。换句话说,for循环可能不会导致性能损失。请记住,17毫秒大约是1帧动画,每秒60帧。

如果您查看本文末尾的屏幕截图,您会注意到即使在测试1 中,所有&#34;脚本编写&#34; (for - 循环的执行)在所有&#34; rending&#34;之前发生。 (再流)。因此,如果您的问题是,#34;浏览器会在循环的每次迭代中交替编写脚本并进行渲染,那么答案就是,至少在Chrome 50中是这样。

对于评论中的fridge_light链接,链接文档从不说明设置display:none不会触发重排;它只包含一个链接到的视频的图表,没有图例。设置display:none 更改布局:文档的高度可能会更改,隐藏元素下方的元素将移动到更接近文档的顶部,与隐藏元素内联的元素将移位内联,浮动元素将改变它周围的位置,等等。因此浏览器必须进行一些计算。

你的问题有点困惑:DOM不一定与页面重新流动有关。例如,重新调整浏览器窗口的大小可能会触发重新流动而不会影响DOM!将display设置为none会从页面布局/流中删除一个元素,但会将其保留在DOM中。

测试1 Test 1

测试2 Test 3

答案 1 :(得分:0)

对于您显示的代码,不,它不是