简体   繁体   English

为什么Chrome渲染JavaScript的速度如此之慢?

[英]Why does Chrome render JavaScript so slowly?

I have a page that contains a random number of rows, each row has 2 cols. 我有一个包含随机行数的页面,每行有2个列。 The challenge is to make this two columns of the same height for each row. 挑战在于为每一行制作相同高度的两列。 I do that with JS. 我用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;
}

When on page are less then 30-40 rows it's all good. 当页面上少于30-40行时,它们都很好。 But, when there is more then 200 rows, chrome start to lag for a couple of secs. 但是,当有超过200行时,铬开始滞后几秒钟。

I've created a demo page here http://jsfiddle.net/YSp76/ . 我在http://jsfiddle.net/YSp76/创建了一个演示页面。

In FF and IE it executes in about 2sec. 在FF和IE中,它在大约2秒内执行。 In chrome I didn't count but is more then 10. 在铬我没有数,但超过10。

The problem is in my code or is a webkit bug? 问题出在我的代码中或者是webkit错误?

It's not a bug, it's just a result of webkit/blink's non-optimal layout strategy. 这不是一个错误,它只是webkit / blink的非最佳布局策略的结果。 Here's what's going on behind the scenes: 这是幕后发生的事情:

  • Changing the column height "invalidates" the layout. 更改列高度“使布局无效”。
  • Querying an offsetHeight requires a valid layout. 查询offsetHeight需要有效的布局。 If the layout is invalid, chrome needs to re-layout the invalid elements. 如果布局无效,则chrome需要重新布局无效元素。

This means that Chrome will re-layout the page 300 times. 这意味着Chrome会将页面重新布局300次。 If you have access to a Mac, Safari 7.0 has excellent tools for debugging this sort of thing (the 'layout timeline'). 如果您可以访问Mac,Safari 7.0具有用于调试此类事物(“布局时间线”)的出色工具。 Chrome also has some debugging tools in the "timeline" view (filter it so only 'Rendering' events appear). Chrome在“时间轴”视图中也有一些调试工具(过滤它以便只显示“渲染”事件)。 For more information on avoiding layouts, see http://gent.ilcore.com/2011/03/how-not-to-trigger-layout-in-webkit.html , although the information presented there is incomplete. 有关避免布局的更多信息,请参阅http://gent.ilcore.com/2011/03/how-not-to-trigger-layout-in-webkit.html ,尽管其中提供的信息不完整。 Unfortunately, the only up-to-date source on the details of the WebKit rendering process is the WebKit source code itself. 不幸的是,关于WebKit渲染过程细节的唯一最新来源是WebKit源代码本身。

To fix your problem, you can simply separate the querying height step from the changing height step. 要解决您的问题,您可以简单地将查询高度步骤与更改高度步骤分开。 This will avoid unnecessary layouts. 这样可以避免不必要的布局。 I've forked your fiddle here: http://jsfiddle.net/4fb2A/ 我在这里分享你的小提琴: 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;
}

However, for layout tasks like this, you should try very hard to create a CSS-only solution. 但是,对于像这样的布局任务,您应该非常努力地创建仅限CSS的解决方案。 Using script is an inappropriate tool for this job, and will alienate visitors who have script turned off. 使用脚本对于这项工作来说是不合适的工具,并且会疏远关闭脚本的访问者。

The chrome profiler (available via right click, inspect element, Profiles) shows that it's the offsetHeight that consumes the largest part, it seems related to this open bug in chrome: chrome profiler(可通过右键单击,检查元素,Profiles)显示它是offsetHeight消耗最大的部分,它似乎与chrome中的这个开放bug有关:

在此输入图像描述

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM