Reading out the end time in browser speed tests

A few weeks back I did some DOM speed tests on mobile browsers (results forthcoming). The most important result of these tests is not the actual values (although they’re interesting), but the fact that I could finally prove a theory that I’ve had in the back of my mind for at least two years now.

Basically, when setting up a speed test you should be very careful to allow the browser to render the result on screen before you close the test by reading out the second timestamp.

An example will clarify this point. A DOM speed test may look roughly as follows:

function testIt() { var startTime = new Date().getTime(); // actual DOM functionality to be tested goes here var endTime = new Date().getTime(); var result = (endTime-startTime)/1000; // print result }

Although this script might seem fine at first sight, it’s not. The problem here is that the entire test, including the time measurements, are wrapped in one function, and that some browsers only applies the result of the test (i.e. the changes in the DOM you want to test) to the screen after the function has ended entirely. Thus the end timestamp is read before the browser has applied the result to the screen.

So what really happens here is the following:

Get start time Perform DOM manipulation in browser memory Get end time and calculate result The function ends, and only now does the browser start to apply the results of the DOM manipulation to the actual DOM.

Not all browsers wait until the end of the function to apply the results, but some do, among which Safari for the iPhone 2.2. These browsers only report the time it takes them to build the new DOM tree in the browser memory, and disregard the time it takes to show it on the screen.

Any testing methodology must work in all browsers, so our test function must work around this problem.

The correct way of conducting this test is setting a timeout for reading out the end time. The function ends when the in-memory DOM manipulation has been done, which allows the browser to apply the changes.

Because the browser uses its complete capacity for applying the changes to the screen, executing the timeout is deferred until it is done, even if that takes far longer than the formal timeout time.

function testIt() { var startTime = new Date().getTime(); // actual DOM functionality to be tested goes here setTimeout(function () { var endTime = new Date().getTime(); var result = (endTime-startTime)/1000; // print result },10) }

What happens now is the following:

Get start time Perform DOM manipulation in browser memory Define a function to get end time and calculate result and set a timeout The function ends, and only now does the browser start to apply the results of the DOM manipulation to the actual DOM. Once the DOM manipulation is finished, the browser is freed up to treat the timeout we set, and now the function that gets the end time and shows the result is executed.

In other words, this allows us to also measure the time the browser needs to show the results on screen.

This is what we really want to know. If the browser is lightning-fast in performing DOM manipulations in its memory, but sluggish in applying them to the screen, the net result for the end user is a relatively sluggish user experience.

This is not a random theoretical musing. I tried both methodologies on Safari iPhone 2.2 in a test that generated 5,000 list items. The first, incorrect, method yields a total time of about 3 seconds, while the second, correct, method yields a total time of about 14 seconds. That’s an 11 second difference.

(I’d be interested in the iPhone 3 results. I deliberately haven’t updated my iPhone yet, because there still are some tests I want to conduct on the 2.2 OS.)

In other words, the iPhone 2.2 takes 3 seconds to perform the necessary calculations in its memory, but subsequently takes 11 seconds to show the changes on screen. It’s slow, in other words. The first method does not reveal that; we need the second one for an accurate reading.

Therefore it’s important that whenever you do speed tests, the end time should be calculated only after the browser has finished applying the results to the screen.

Comments are closed.