Mattias Wallander

Developing myself

FPS Counter for Firefox

| Comments

For hardware accelerated content in Chrome, you can get the number of painted frames per second by switching it on in about:flags.

Firefox also has a flag like that (layers.acceleration.draw-fps in about:config) but it seems a bit shaky. I have gotten it to work on Firefox Mobile but not on desktop (only tried Linux and Windows though). For Windows there is a fixed bug that is targeted for Firefox 32. And on Linux, hardware acceleration is generally problematic as I understand it.

Therefore I wanted to write an FPS counter that worked even if all the constraints were not fulfilled. So here it is, a simple FPS counter that places itself in the bottom right corner and updates about once a second.

FPS Counter
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
(function () {
    var overlay, lastCount, lastTime, timeoutFun;

    overlay = document.createElement('div');
    overlay.style.background = 'rgba(0, 0, 0, .7)';
    overlay.style.bottom = '0';
    overlay.style.color = '#fff';
    overlay.style.display = 'inline-block';
    overlay.style.fontFamily = 'Arial';
    overlay.style.fontSize = '10px';
    overlay.style.lineHeight = '12px';
    overlay.style.padding = '5px 8px';
    overlay.style.position = 'fixed';
    overlay.style.right = '0';
    overlay.style.zIndex = '1000000';
    overlay.innerHTML = 'FPS: -';
    document.body.appendChild(overlay);

    lastCount = window.mozPaintCount;
    lastTime = performance.now();

    timeoutFun = function () {
        var curCount, curTime;

        curCount = window.mozPaintCount;
        curTime = performance.now();
        overlay.innerHTML = 'FPS: ' + ((curCount - lastCount) / (curTime - lastTime) * 1000).toFixed(2);
        lastCount = curCount;
        lastTime = curTime;
        setTimeout(timeoutFun, 1000);
    };

    setTimeout(timeoutFun, 1000);
}())

Just copy the code and paste it into your console. The easiest way to use it though, is as a bookmarklet. Just drag this FPS Counter link to your bookmarks toolbar.

The functionality I am using is a Firefox specific property on the window object called mozPaintCount. It contains the number of times the document has been painted since it was created.

Note that mozPaintCount shows actual paints, not how many would be possible at a maximum rate. There are several things that make a browser lower the number of paints, e.g. when switching to another tab. Also, most of the time (depending on hardware), the maximum rate is usually capped at 60 FPS since there is no need to update more often than the screen refreshes itself.

There are solutions where the code counts the number of times that a callback for requestAnimationFrame is called, but that does not exactly correspond to the number of actual paints done.

Also, I use performance.now() instead of Date.now(), which is independent of the system clock and has a (up to) microsecond resolution.

Specifications Don’t Say Everything

| Comments

Looking at how good the largest web browsers are today compared to how the situation was some years back, it’s easy to be fooled that they all behave the same when they “follow the specifications.” That is not really how it works though. Even when strictly implementing a standard there are choices to be made. This has as a result that in some situations different browsers have different behaviors even though they adhere to the same specification.

Recently I ran into two of these situations and got stuck since I hadn’t been reminded for a while that these differences exist.

Border Collapse

Last week I was styling tables for a new corporate identity design (CID) for a customer. Like probably most people nowadays I don’t use tables that much, and when I do I seldom style them since they usually have a style set up already. So when I had this strange 1px top border at one point that I couldn’t grasp where it came from I got a little frustrated.

Being a Firefox guy, I had checked Firebug and saw that there was a top border on the table (i.e., not on any table cells). I wanted to remove this so I looked for a rule that could have made the border on the table appear. Unfortunately, I really couldn’t understand where it came from.

I continued to check in Firefox’s own developer tools (it’s gotten really good nowadays) but couldn’t find it there either. Frustrated I checked in Chrome and found it immediately. No, it didn’t have to do with Chrome’s developer tools being better. It had to do with Firefox’s way of internally representing collapsed borders.

I checked the specification for collapsing borders. When collapsing borders the border width should be the maximum width of the two borders and centered on the grid lines between the cells. Centering works fine for even numbers of pixels but it’s not as obvious for odd numbers. Therefore there is an addition that says that for an odd number of pixels, user agents must find a consistent rule for rounding them off. And this is part of why I couldn’t find my top border.

It turns out that when Firefox collapses the top border of the table and the top border of the table cells in the first row, it always puts the odd pixel on the table’s border when representing this in the developer tools. I would guess this is easier to spot when the border width is 3, 5 or 27 pixels, but when it’s 1 it’s not as clear. At least not when the border is set on the table cells instead of the table itself.

The way Chrome does it is that it simply shows the original values of both borders. I can see the benefits of both strategies. In Chrome it’s easier to see what values were actually set on each border. In Firefox you see the end result.

Line Height

Then we have the line-height for input elements in Firefox. There is nothing wrong with how Firefox does it – they don’t break the specification – but they are the only ones that set a fixed line-height on input fields. In 2002 they decided to set the line-height to “normal !important” which stops it from being changed in a web site’s CSS.

The original problem is that when a line-height is too small on an input field, the field behaves strangely (e.g. the text can be hard to read). Firefox solved this by always having the line-height value of “normal” (roughly 1.2) while the other browser vendors have solved it by setting a minimum value that it can’t go below.

If you are not aware of this, it can cause some headache when you think you’ve gotten your form element styles ready and just want to have a quick check in other “standards compliant browsers.” You think there won’t really be any differences for simple styling like this, but then you notice that the texts in your fields are placed differently in the other browser and you cannot figure out why.

A fix for the line-height issue is on its way though and will be in Firefox 30. After that release, you will be able to set the line-height of input fields in Firefox as long as you do not want it to be less than 1.0.

Beware

What I want to point out by this is that you cannot count on everything working exactly the same in different browsers even when they are ranked as the best ones and said to be “following the specifications.” Beware that there still will be different solutions to the choices that need to be made, and sometimes you will find that out the hard way.

First!

| Comments

This is my first technology blog. I’m starting it for two reasons. The first is that I somehow hope that it can be of help to people having the same problems that I do or that want to learn more about the technologies I write about. The second reason is to help myself getting better through explaining the subjects to others. They say you don’t really know something until you do that.

Oh, I have a third reason too. I think it’s going to be fun!