javascript - 为什么 Chrome 渲染 JavaScript 这么慢?

标签 javascript google-chrome

我有一个包含随机行数的页面,每行有 2 列。 挑战在于使每一行的这两列具有相同的高度。 我用 JS 做到这一点。

var len = document.getElementById("translateContainer").children.length;

for(var i = 0; i<len; i++)
{
    var height = document.getElementById("origin_"+i).offsetHeight + 'px',
        col1 = document.getElementById("column_"+i),
        col2 = document.getElementById("column_sec_"+i);

    console.log(i);

    col1.style.height = height;
    col2.style.height = height;
}

当页面少于 30-40 行时,一切都很好。 但是,当超过 200 行时,chrome 开始延迟几秒钟。

我在这里创建了一个演示页面 http://jsfiddle.net/YSp76/ .

在 FF 和 IE 中,它在大约 2 秒内执行。在 chrome 中,我没有数过,但超过 10 个。

问题出在我的代码中还是 webkit 错误?

最佳答案

这不是bug,只是webkit/blink 的非最优布局策略导致的结果。以下是幕后发生的事情:

  • 更改列高会使布局“无效”。
  • 查询 offsetHeight 需要有效的布局。如果布局无效,chrome 需要重新布局无效元素。

这意味着 Chrome 将重新布局页面 300 次。如果您可以使用 Mac,Safari 7.0 具有出色的调试此类功能的工具(“布局时间线”)。 Chrome 在“时间轴” View 中也有一些调试工具(对其进行过滤,以便只显示“渲染”事件)。有关避免布局的更多信息,请参阅 http://gent.ilcore.com/2011/03/how-not-to-trigger-layout-in-webkit.html ,尽管那里提供的信息不完整。不幸的是,关于 WebKit 渲染过程细节的唯一最新来源是 WebKit 源代码本身。

要解决您的问题,您可以简单地将查询高度步长与更改高度步长分开。这将避免不必要的布局。我在这里 fork 了你的 fiddle :http://jsfiddle.net/4fb2A/

var len = document.getElementById("translateContainer").children.length;

var origin_height = [];

for(var i = 0; i<len; i++)
{
    origin_height[i] = document.getElementById("origin_"+i).offsetHeight + 'px';
}

for(var i = 0; i<len; i++)
{
    var height = origin_height[i],
        col1 = document.getElementById("column_"+i),
        col2 = document.getElementById("column_sec_"+i);

    console.log(i);

    col1.style.height = height;
    col2.style.height = height;
}

但是,对于像这样的布局任务,您应该非常努力地创建一个仅使用 CSS 的解决方案。使用脚本是不适合这项工作的工具,并且会疏远关闭脚本的访问者。

关于javascript - 为什么 Chrome 渲染 JavaScript 这么慢?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20886951/

相关文章:

javascript - jQuery 在文本有限时隐藏“显示更多”按钮

javascript - 在 stateChangeStart 中从子状态访问父状态的参数

javascript - 只能添加 dom 元素但不能删除它们

css - 使用 Chrome Devtools 调试 CSS 动画

javascript - 设置cookie并自动登录

c# - UI 自动化的 Google Chrome 可访问树缓存问题

javascript - ValidationError : Invalid options object. CSS Loader 已使用与 API 模式不匹配的选项对象初始化

javascript - 将模块中的函数绑定(bind)到 onclick 事件

javascript - 我想根据设备显示不同的图像

javascript - 巨大的 JavaScript HTML5 blob(来自大型 ArrayBuffers)在客户端构建一个巨大的文件