javascript - 显示 : none in a for loop and its affect on reflow

标签 javascript css reflow

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

for (i=0; i<100; i++){
    document.getElementById(elem + i).style.display="none";
}

我才刚刚开始了解浏览器回流;但是,我目前的理解是,此循环会导致它设置为不显示的 100 个元素中的每一个元素都发生回流。

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

此代码在渲染新页面时使用。

最佳答案

Chrome Developer Tools时间轴是测试这类问题的好方法,尤其是因为“我认为的那样可怕”是相当主观的。

我测试了您在此 fiddle 中发布的代码.将此称为测试 1

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

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

  • 测试 1 中,渲染花费了 17.6 毫秒
  • 测试 2 中,渲染花费了 1.5 毫秒

因此经验答案是肯定的,与替代(理想)方法相比,测试代码需要 10 倍以上的计算时间来重排页面布局。在不了解提取它的代码的情况下,很难说所使用的方法是否合适或必要。

例如,如果要隐藏的元素没有整齐地包裹在它们自己的包装器中 <div> ,优化难度大。一种避免 for 的策略循环将是为元素分配一个“hideable”类,并设置一个 CSS 规则,如 wrapper.hideChildren > .hideable { display:none; } .然后,当我们将类“hideChildren”分配给包装器时,标记的元素将被隐藏。 Using this strategy ,我只能将渲染时间缩短到 15ms,或者当包装器在操作之前从 DOM 分离并在之后重新附加时 10ms。换句话说,for循环可能不会招致那么多的性能损失。请记住,17 毫秒大约是每秒 60 帧的动画的 1 帧。

如果您查看本文末尾的屏幕截图,您会注意到即使在测试 1 中,所有“脚本”(for 循环的执行)都发生在全部“rending”(重新流动)。因此,如果您的问题是“浏览器是否会在循环的每次迭代中交替执行脚本和渲染”,那么答案是不会,至少在 Chrome 50 中是这样。

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

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

测试 1 Test 1

测试 2 Test 3

关于javascript - 显示 : none in a for loop and its affect on reflow,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37494330/

相关文章:

javascript - 回流和重绘(repaint)的替代方案

javascript - 如何修复 webpack 错误 : "you may need an appropriate loader to handle this file type." when I useing webpack to load css files

html - CSS 媒体查询移动与桌面 : Mobile too zoomed out | Materialize

html - Internet Explorer Div 宽度问题

firefox - 有没有办法在繁重的 DOM 操作期间暂停回流?

css - Chrome 的重新计算样式事件涉及什么?

javascript - 有没有办法防止橡皮筋但仍然允许 "click"事件?

javascript - Angular JS 多个 Controller 不工作

javascript - 我试图更好地理解 `this` 的用法。该示例很冗长,但其目的是为了更好地理解

html - Angular 6 - 如何根据条件禁用 div