When working with a very dynamic UI (think Single Page App) with potentially large JS libraries, view templates, validation, ajax, animations, etc... what are some strategies that will help minimize or reduce the time the browser spends on reflow?
For example, we know there are many ways to accomplish a DIV size change but are there techniques that should be avoided (from a reflow standpoint) and how do the results differ between browsers?
Here is a concrete example:
Given a simple example of 3 different ways to control the size of a DIV when the window is resized, which of these should be used to minimize reflows?
http://jsfiddle.net/xDaevax/v7ex7m6v/
//Method 1: Pure Javascript
function resize(width, height) {
var target = document.getElementById("method1");
target.setAttribute("style","width:" + width + "px");
target.setAttribute("style", "height:" + height + "px");
console.log("here");
} // end function
window.onresize = function() {
var height = (window.innerHeight / 4);
var width = (window.innerWidth / 4);
console.log(height);
resize(height, width);
}
//Method #3 Jquery animate
$(function() {
$(window).on("resize", function(e, data) {
$("#method3").animate({height: window.innerHeight / 4, width: window.innerWidth / 4}, 600)
});
});
It's best to try and avoid changing DOM elements whenever possible. At times you can prevent reflow at all by sticking to CSS properties or, if required, using CSS' transform
s so that the element itself is not affected at all but, instead the visual state is just changed. Paul Lewis and Paul Irish go into detail about why this is the case in this article.
This approach will not work in all cases because sometimes it's required to change the actual DOM element, but for many animations and such, transform
s brings the best performance.
If your operations do require reflow, you can minimize the effect it has by:
Nicole Sullivan posted a pretty good article on the subject that goes into more details of browser reflows and repaints.
If you're actually changing the DOM, not DOM properties, it's best to do it in larger chunks rather than smaller ones like this Stack Overflow post suggests.
In the example you provided, the second method is the best because it is using CSS properties without needing JavaScript. Browsers are pretty good at rendering elements who's dimensions and position is determined solely by CSS. However, it's not always possible to get the element where we need to be with pure CSS.
The worst method is by far the third because jQuery's animate is terribly slow to start out with, but making it fire on resize makes the animates stack on top of each other so it lags wayyy behind if you resize it much at all. You can prevent this by either setting a timeout with a boolean to check whether it's been fired already or, more preferably, don't use jQuery's animate to do this at all but instead use jQuery's .css()
since the resize function fires so often that it will look animated anyway.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With