Why does Chrome make JavaScript so slow?

I have a page containing a random number of rows, each row has 2 columns. The challenge is to make these two columns the same height for each row. I am doing this with 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; } 

If the page has less than 30-40 lines, all this is good. But, when there are more than 200 lines, chrome starts to lag a couple of seconds.

I created a demo page here http://jsfiddle.net/YSp76/ .

In FF and IE, it runs after about 2 seconds. In chrome, I did not count, but more than 10.

Is there a problem in my code or a webkit error?

+7
javascript google-chrome
source share
2 answers

This is not a mistake, it is simply the result of a sub-optimal website hosting / blinking strategy. Here's what happens behind the scenes:

  • Changing the height of a column will invalidate the layout.
  • A request for offsetHeight requires a valid layout. If the layout is invalid, chrome requires the re-arrangement of invalid elements.

This means that Chrome will reset the page 300 times. If you have access to a Mac, Safari 7.0 has great tools for debugging these kinds of things ("build timeline"). Chrome also has some debugging tools in the β€œtimeline” view (filter it so that only β€œRendering” events are displayed). For more information on avoiding layouts, see http://gent.ilcore.com/2011/03/how-not-to-trigger-layout-in-webkit.html , although the information provided there is incomplete. Unfortunately, the only updated source of information about the WebKit rendering process is the WebKit source code.

To fix the problem, you can simply separate the request height step from the height change step. This will avoid unnecessary layouts. I unwound your fiddle here: 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 build tasks like this, you should try very hard to create a CSS-only solution. Using a script is an unacceptable tool for this work and will alienate visitors who have the script disabled.

+4
source share

The chrome profiler (accessible by right-clicking, check item, profiles) shows that this is offsetHeight, which consumes the most part, seems to be related to this open error in chrome:

enter image description here

+3
source share

All Articles