Effectively measuring browser framerate using CSS

June 27, 2011 by David Corvoysier

Most browsers now provides features allowing the web developers to design animated user interfaces that were before only available through proprietary plugins such as Flash or Silverlight.

Namely, CSS 3 transformations, transitions and animations, HTML 5 canvas or WebGL are the new kids on the block (for those wondering: yes, I was a teen in the 80s), and have received a lot of attention since a certain mr jobs claimed that no flash plugin would ever make it to his products.

So: what happens when a browser feature becomes widely implemented and popular ? Competition between implementations, of course !

The trouble is that it may be relatively easy to evaluate javascript performance (although one may argue that event javascript benchmarks are biased), but it is a bit more complicated to evaluate actual browser framerate.

How browser rendering is implemented

Typically, and although they may use background processes to perform specific asynchronous tasks (such as resource downloads for instance), web browsers do render each web page in a single thread, splitting the CPU time between javascript and rendering tasks.

Typically, on every frame, the browser executes some javascript functions piled in a javascript code queue (with a priority given on timed functions) for a given amount of time (typically 50ms), and then checks whether the page needs to be refreshed or not. If the page needs to be refreshed (either because, the DOM itself has been modified or because a new CSS rule modifies the layout, or for many other reasons …), it calculates the new page layout, isolates the portion of the page that it needs to refresh (sometimes called the “damaged” or “dirty” region), and renders it to its “backing store” (typically an internal buffer where all the drawing stuff occurs). Once done, it pushes the modified frame on screen using whatever mechanism the host operating system provides.

The important thing to note here is that ultimately, the operating system video drivers decide when the frame is actually pushed to screen: this means that trying to achieve a framerate that exceeds the video output synchronisation rate (typically 60Hz) is useless. As a matter fo fact, most browsers have a “framerate cap” hard-coded somewhere to avoid unecessary rendering operations (Chrome provides an option to remove this cap in about:flags).

Why javascript alone can’t be used to calculate FPS

Since actual frame rendering is not directly related to javascript based DOM or CSS modifications, relying solely on javascript loops to measure an animation framerate will most likely lead to very optimistic results (see for instance the Bubblemark javascript based benchmark that gives awesome results even when the actual rendering looks completely frozen).

Even worse, with CSS triggered animations, there is no way for the javascript to be notified of a new frame being rendered (actually, the whole point of this new CSS stuff is to avoid the javascript overhead).

How CSS can be used to calculate FPS (with a little javascript also)

Having thought a little about this issue, I came up with the idea of using CSS itself to evaluate the actual rendering framerate of a page.

The principle is quite simple:
- insert a very simple CSS animated item in a page,
- calculate the computed position of this item at regular intervals,
- every second that has elapsed, count the number of different positions occupied by the item.

Pretty dumb, uh ? Well, maybe, but it gives surprisingly accurate results, actually …

Obviously, this only works on browser supporting CSS transitions/animations, but these are actually the implementations we want to evaluate, so this isn’t really an issue.

The FPSMeter script

I have developed a little script that does just what I’ve described in the previous paragraph.

Get the script Here.

Here is a brief HowTo:

1 – Include the FPSMeter script to your page

    <script type="text/javascript" src="<path_to>/FPSMeter.js"></script>

2 – Add two call-back functions to your page to monitor progress and gather the final results

function log(fps){
// Do some stuff here with current FPS
}
function end(minfps,avgfps,maxfps){
// Do some other stuff here with min, max and avg fps
}

3 – In your page initialization code, instantiate an FPSMeter object, providing the call-backs as parameters

fpsMeter = new FPSMeter(log,end);

4 – Run the FPS meter for n seconds

fpsMeter.run(n);

Pure CSS Carousel

June 22, 2011 by David Corvoysier

I have been playing for a while with CSS transitions and animations, but I didn’t take the time to post anything on the subject.
Here is a small example of a pure CSS carousel using CSS3 animations.

It works on Chrome, Safari (with a few z-index glitches), and hopefully soon on Firefox 5.0.

Kaizoumark: a browser animation benchmark

June 17, 2011 by David Corvoysier

After years of Flash dominance, HTML5 and CSS3 are now bringing many eye-candy features allowing the development of pure-web rich user interfaces (Canvas, CSS animations & transitions, WebGL).

At the same time, the development of native applications on smartphones & tablets have raised the users level of expectations towards GUI to a point that “plain old web” user interfaces are not an option anymore.

But do current implementations live up to the expectations ? This has yet to be demonstrated …

The sad truth is that even on desktop, the CPU alone cannot cope with the level of complexity that is today required to develop a fancy user interface, and browser vendors are struggling to take advantage of hardware accelerations provided by blitters or GPUs. Due to the huge diversity of hardware configurations available, this leads to a very fragmented landscape for the poor web developer.

That said, how can we users help things getting better ? By providing feedback on how well their implementation behave to the browser developers …

For that purpose, I have designed a small browser animation benchmark test that calculates the number of frames the browser is displaying per seconds while an animation plays.

Note: If you want to know how the framerate is evaluated, see this post.

It now only works for Firefox, Chrome, Safari and Opera (IE is not supported).

It currently only tests CSS 2D features, but I will add more tests later.

At some point in the future I will also try to add some mechanism to have results gathered in a database, but in the meantime, you can post your result as a comment, specifying your hardware configuration, operating system and browser version.

Click on the link below to benchmark your browser.

kaizoumark

Some results:

On a Dell Latitude D620 Laptop running Windows XP:

Chrome 13.0.782.24

Test 1 2 3 4
CSS 3 Transitions (width+height) 38 fps 38 fps 32 fps 17 fps
CSS 3 Transitions (width+height+opacity) 38 fps 37 fps 17 fps 8 fps
CSS 3 Animations (top+left) 38 fps 38 fps 35 fps 16 fps

Firefox 5

Test 1 2 3 4
CSS 3 Transitions (width+height) 59 fps 53 fps 26 fps 13 fps
CSS 3 Transitions (width+height+opacity) 59 fps 33 fps 7 fps 2 fps
CSS 3 Animations (top+left) 57 fps 49 fps 20 fps 10 fps

Safari 5.0.3

Test 1 2 3 4
CSS 3 Transitions (width+height) 40 fps 40 fps 34 fps 19 fps
CSS 3 Transitions (width+height+opacity) 41 fps 38 fps 12 fps 5 fps
CSS 3 Animations (top+left) 40 fps 40 fps 36 fps 18 fps

Opera 11.11

Test 1 2 3 4
CSS 3 Transitions (width+height) 48 fps 47 fps 46 fps 40 fps
CSS 3 Transitions (width+height+opacity) 49 fps 47 fps 35 fps 18 fps
CSS 3 Animations (top+left) NA NA NA NA

On an Iphone 3GS running iOS 4.3.3:

Test 1 2 3 4
CSS 3 Transitions (width+height) 23 fps 22 fps 4 fps 2 fps
CSS 3 Transitions (width+height+opacity) 31 fps 3 fps 1 fps 1 fps
CSS 3 Animations (top+left) 18 fps 23 fps 7 fps 3 fps