Browserscope

Reflow Bookmarklet!

What are the Reflow Tests?

Reflow in a web browser refers to the process whereby the render engine calculates positions and geometries of elements in the document for purpose of drawing, or re-drawing, the visual presentation. Every browser has its own logic for doing, and sometimes not doing, these calculations. Dynamic changes to the document's styles and contents will cause reflow to occur - being mindful of the things that slow down this process can lead one to creating faster web pages.

How the Reflow Timer Works

Reflow Timer is a fairly naive Javascript-driven test to see how long it takes for the browser to return control to the Javascript engine following one or many changes done in script to an element. Before each test is performed, we attempt to flush the browser's render queue(if a browser uses this optimization) by asking for that element's offsetHeight. This idea was suggested by Mozilla's render-engine guru David Baron, and so it at least works in Gecko to cause the render engine to perform all queued-up changes - which is essential for correctly providing the calculated value of the element's fully rendered height. (See the ReflowTimer.flushRenderQueue_ method in reflow_timer.js

Once satisfied that the render queue has been flushed, we give the browser a little time to rest, then set a timer. We perform whatever operations are in a particular test (almost always a set operation on element.style), and then we again flush the render queue and capture the time again right after that. We get the delta, and voila - we call that the reflow time.

This approach is certainly not flawless (Javascript timers can be @ 15ms inaccurate), but it appears to work in all browsers in non-debug builds - therefore giving us a time that should be something akin to what real-world users would experience in terms of the interaction-blocking time caused by selector match time + position calculations (aka "reflow" in our tests).

What's up with using the Acid1 test?

Acid1 (Wikipedia) has been around for a 11 years now and tests core compatibility with CSS1. This test causes a nice balance of CSS selector matching plus layout changes and has the added advantage that we didn't write it.

More About Each Test

Display Block

This test takes an element and sets its style.display="none". According to the folks at Mozilla this has the effect of taking an element out of the browser's "render tree" (the in-memory representation of all of results of geometry/positioning calculations for that particular element). Setting an element to display="none" has the additional effect of removing all of an element's children from the render tree as well. Next, the test resets the element's style.display="", which sets the element's display back to its original value. Our thinking was that this operation ought to approximate the max cost of reflowing an element on a page since the browser has to recalculate all positions and sizes for every child within the element as well as any changes to the overall document.

Visiblility None

Much like the display test above, this test sets an element's style.visibility="hidden" and then resets it back to its default, which is "visible". This change should be less costly than changing display from "none" to the default since the browser should not be purging the element from the render tree.

Non Matching Class

This test adds a class name to an element where that class name is not present in the document's CSS object model. This tests CSS selector match time, and more specifically against selectors with classnames.

Four Reflows by Class

This test adds a class name to an element that will match a previously added CSS declaration added to the CSSOM. This declaration is set with four property value pairs which should in and of themselves be capable of causing a 1x reflow time. For instance, "font-size: 20px; line-height: 10px; padding-left: 10px; margin-top: 7px;". This test aims to test whether reflow operations occur in a single queue flush or if they are performed one at a time when these changes are made via a CSS classname. This test is a sort of opposite to the Four Reflows By Script.

Four Reflows by Script

Like the Four Reflows By Class test, but instead this test has four lines of Javascript, each of which alters the style object with a property/value that by itself could cause a 1x reflow time.

Two Reflows by Script

Like the Four Reflows By Script test, except with only two lines of Javascript.

Padding px

This test sets style.padding="FOOpx", aka padding on all sides of the box model.

Padding Left px

This test sets style.paddingLeft="FOOpx", aka padding on only the left side of the box.

Font Size em

This test changes an element's style.fontSize to an em-based value.

Width %

This test sets an element's style.width="FOO%"

Background Color

This test sets an element's style.background="#FOO", aka a hexadecimal color.

Overflow Hidden

This test sets an element's style.overflow="hidden" and then back again, timing the cost of an element returning to the default overflow which is "visible"

Do Nothing / OffsetHeight

This test does nothing other than the request for offsetHeight after already having done so. Theoretically, this test is something like a control for our test and should have a 0 or very low time.

Additional resources

CC0 | Home | FAQ | API | UA Parser | News | Browser Resources | Code | Submit a Bug | Downloads | Mailing List | Contact