Search

1/27/2008

Efficient JavaScript - Opera Developer Community

Efficient JavaScript - Opera Developer Community
Avoid using eval or the Function constructor

The eval function is especially bad, as the contents of the string passed to eval cannot be known in advance. Since the code is interpreted in the context of the call to eval this means that the compiler cannot optimise the surrounding context, and the browser is left to interpret much of the surrounding code at runtime. This adds an aditional performance impact.

Don't use try-catch-finally inside performance-critical functions
Avoid using global variables
To begin with, if code inside a function or another scope references that variable, the script engine has to step up through each scope in turn until it reaches the global scope. A variable in the local scope will be found more quickly.

Primitive operations can be faster than function calls
A.push('foo');A[A.length] = 'foo'; 來得慢,
因為A.push是一個 function call

Pass functions, not strings, to setTimeout() and setInterval()
The setTimeout() and setInterval() methods are very closely related to eval. If they are passed a string, then after the specified delay, that string will be evaluated in exactly the same way as with eval, including the associated performance impact.

DOM - Repaint and reflow
Repaint - also known as redraw - is what happens whenever something is made visible when it was not previously visible, or vice versa, without altering the layout of the document. An example would be when adding an outline to an element, changing the background color, or changing the visibility style.
A reflow is a more significant change. This will happen whenever the DOM tree is manipulated, whenever a style is changed that affects the layout, whenever the className property of an element is changed, or whenever the browser window size is changed. The engine must then reflow the relevant element to work out where the various parts of it should now be displayed. Its children will also be reflowed to take the new layout of their parent into account. Elements that appear after the element in the DOM will also be reflowed to calculate their new layout, as they may have been moved by the initial reflows. Ancestor elements will also reflow, to account for the changes in size of their children. Finally, everything is repainted.
Reflows are very expensive in terms of performance, and is one of the main causes of slow DOM scripts, especially on devices with low processing power, such as phones. In many cases, they are equivalent to laying out the entire page again.

Taking measurements - since asking for offsetWidth forced the element to reflow in order to answer you question (because it had a pending change to style).
As stated earlier, the browser may cache several changes for you, and reflow only once when those changes have all been made. However, note that taking measurements of the element will force it to reflow, so that the measurements will be correct. The changes may or may not not be visibly repainted, but the reflow itself still has to happen behind the scenes.

This effect is created when measurements are taken using properties like offsetWidth, or using methods like getComputedStyle. Even if the numbers are not used, simply using either of these while the browser is still caching changes, will be enough to trigger the hidden reflow. If these measurements are taken repeatedly, you should consider taking them just once, and storing the result, which can then be used later.

沒有留言: