Blog
September 6th, 2008
Summary: JavaScript Benchmarks aren't adapting well to the rapid increase in JavaScript engine performance. I provide some simple tests for verifying this and propose a modified setup which could be used by all JavaScript Benchmarks to achieve high-quality results.
There now exists three, what I would consider to be, major JavaScript performance benchmarks. Each are released by a major browser vendor. WebKit released SunSpider, Mozilla released Dromaeo, Google released the V8 Benchmark.
Each suite has a variety of tests and a test runner. I'm currently interested in one thing: The quality of the test runner that each of these suites provides.
There are three points that any test runner tries to achieve:
- Retrieving accurate numbers. Another way to phrase it: "Retrieving stable numbers." If you run the test suite multiple times will you get identical, or near-identical, numbers?
- Reducing the possible error. Does the suite attempt to quantify how much possible error there could be in their results? How large is the error?
- Reducing run time. How long does it take to run each test?
The ideal suite would be one that's capable of running an individual test as quickly and accurately as possible with virtually no error. However, in order to get those numbers you need to carefully chose what style of tests you wish to run.
I quantify the current field of tests into three categories:
Slow-running tests: These tests generally take a couple hundred milliseconds on an average consumer machine. This is the style of tests that you generally see in SunSpider and occasionally in Dromaeo. These tests have a distinct advantage: They are generally quite accurate. You don't need to run them very many times (say about 5) in order to get a consistent picture of how the test will run.
Moderate-running tests: These tests take less than one hundred milliseconds. You'll see these tests in Dromaeo. These tests need to be run quite a few times (20-30) in order to get a better picture of their speed.
Fast-running tests: These tests take less than ten milliseconds. You'll see these tests in the V8 Benchmark and in Dromaeo. These tests must be run many, many, times (usually close to a thousand) in order to weed out any possible error. If you were to run one 10ms test 5 times - and get a single result of 11ms that would introduce a significant level of error into your results. Consider tests that take 0-1ms. A deviation within that range can instantly cause error levels around 50% to occur, if enough test iterations aren't completed.
Looking at the above categories the solution seems obvious: Use slow-running tests! You get to run them fewer times and you get accurate results - everything's peachy! But here's the problem: The speed of JavaScript engines are increasing at a rate faster than test suites can adapt. For example, SunSpider was initially developed with all tests running at equal speeds on a modern computer. Now that speed improvements have come along, though, (WebKit improvements, then Mozilla, then SquirrelFish, then TraceMonkey, then V8) those results don't even remotely resemble the tests of old. Most of the results have moved down into the moderate-running range of tests, some even into the fast-running range - but here's the problem: They're still only running the originally-designed number of loops. An example of the difference:
This means that a browser is running a test for 5-10 loops (in both SunSpider or Dromaeo) but the speed of the test no longer matches that assigned number of iterations. At first glance you could say one of two things: 1) Increase the difficulty of the tests or 2) Have them run for more iterations. There are problems with this, though.
While you certainly could increase the complexity of existing tests the result would be a never-ending battle. Improvements would have to land every couple months in order to keep up with the pace of improvement. This would work ok in Dromaeo (since it has versioned tests) but not all suites can handle this behavior. Additionally this now makes the tests less-useful for measuring slower browsers (the tests now take an absurd amount of time to complete as opposed to the very-plausible numbers from before).
Additionally, you could increase the number of test iterations that would occur but not without assigning specific iteration counts to each individual tests. And this is the full problem: How do you know what numbers to choose? Raising the number to 20 iterations may help one browser - but what about another browser which will need 100 iterations to get a proper count?
This leaves us in a bind. Browsers keep getting faster at tests, test suites do the wrong number of iterations, causing the error level to continually increase:
We should take a step back and look at what the test suites are doing to counter-act the above trend from happening - if anything at all.
SunSpider was originally dominated by long-running tests running 5 times each. The tests use to be long-running but are now only in to the medium to fast-running range (depending on the browser). This has caused the accuracy to decrease and error level to increase. Increasing the number of iterations would help (but hinder older browser performance).
Dromaeo has a range of tests (fast, moderate, and long-running) each running 5-10 times each. Dromaeo attempts to correct the number of iterations run, right now, but kind of fails when doing so. It looks at the results of past iterations (especially the error level generated by the results) and decides to run more tests until a stable error level is achieved. The problem with this is the samples are no longer being independently determined. Whereas test runs 1-5 were independent, test runs 6-10 were not (they're only being run due to the fact that previous test runs provided poor results). So while the results from Dromaeo are hyper-stable (they're the most stable performance test that we run at Mozilla) they're not determined in a proper statistical manner. Thus Dromaeo needs to be changed in order for people to be able to gather accurate results without sacrificing its statistical integrity.
The V8 Benchmark takes a completely different strategy for its fast-running tests: Instead of running for a pre-determined number of iterations each test is run continuously until a second of time has passed. This means that individual tests frequently run anywhere from 50-200 times (depending on the machine and browser they run on). Currently the V8 Benchmark does suffer from one shortcoming: There is no error calculation done. Both SunSpider and Dromaeo fit the results to a t-distribution and compute the possible error of the results whereas the V8 Benchmark just leaves them as is.
However, the V8 Benchmark does bring up a very interesting strategy. By picking tests that are simpler (and, arguably, most current complex tests will become "simple" as engines rapidly improve) and running them more times (relative to the complexity of the test) the results become much more stable.
Consider the result: Fast-running tests end up having a smaller error range because they are able to run more within a given allotment of time. This means that the test runner is now self-correcting (adjusting the number of iterations seamlessly). Since all JavaScript engines are getting faster and faster, and complex tests are running in shorter and shorter amounts of time, the only logical conclusion is to treat all tests as if they were fast tests and to run them a variable number of times.
We can test this hypothesis. I've pulled together a simple demo that tests the computational accuracy of the three styles of test (Simple - or Fast-running, Moderate, and Complex - or Slow-running) against the two different types of suites: "Max" style (the style implemented by the V8 Benchmark) and "Fixed" style (the style implemented by SunSpider and Dromaeo). The results are quite interesting:
Fast and moderate-speed tests are incredibly accurate with the max-style of test running. Often their error is no more than 2% (which is really quite acceptable). The quality degrades for the complex tests, but that's ok. Complex tests could be tweaked to consume less resources (thus allowing them to iterate more times and become more accurate).
Right now the accuracy of slow-to-moderate tests in fixed run test suites are suffering from increased rates of error as the engines get faster (as can be seen in the above chart).
The major change that would need to be made to the flexible style of execution (at least the one implemented in the V8 Benchmark) would be some form of error checking and t-distribution fitting. In V8 a series of tests are run over the course of one second. I propose that the resulting number (the total number of tests executed) be saved and the tests are repeatedly run again (perhaps 5 times, or so). The resulting set of 5 numbers (representing, potentially, thousands of test runs) would then be analyzed for quality and error level. I have this measure completely mocked up in my sample test measurement.
The relevant portion of the code is here:
function runTest
(name, test, next
){
var runs =
[], r =
0;
setTimeout(function(){
var start = (new Date).getTime(), diff = 0;
for ( var n = 0; diff < 1000; n++ ) {
test();
diff = (new Date).getTime() - start;
}
runs.push( n );
if ( r++ < 4 )
setTimeout( arguments.callee, 0 );
else {
done(name, runs);
if ( next )
setTimeout( next, 0 );
}
}, 0);
}
Switching to a flexible style of text execution has many benefits:
- It'll help to keep the rate of error small for most tests (especially if the tests are tailored to be smaller in nature).
- It'll allow the suite to gracefully adapt over time, as engines speed up, without sacrificing the ability to work on old engines.
- The maximum number of runs (and, thus, the maximum amount of accuracy) will occur for the engines that are able to complete the tests faster. Since the greatest amount of competition is occurring in these high numbers (as opposed to in older user agents, where there is no progress being made) granting them the most accurate numbers possible makes this ideal.
I plan on prototyping this setup into Dromaeo and releasing it shorting. It'll take much longer to run the full test suite but the result will be quite worth it.
Tags: webkit, tracemonkey, v8, javascript, mozilla
26 Comments on 'JavaScript Benchmark Quality'
August 25th, 2008
The final version of Firebug 1.2 has been released. The release should be up on the Mozilla Add-ons site today, but it's also up on GetFirebug.com right now.
John J Barton and Jan Odvarko put a ton of work into this release (you may have noticed the rapid-fire series of beta releases last week - just trying to smooth out the rough edges).
There have been a number of improvements made (not to mention countless bug fixes). Some of the major points of this release include:
Firefox 3 support.
If you've been using the Firebug 1.2 betas you're already on top of this. Now is a good time to verify the version of Firebug that you're using. Go to Tools > Add-ons in Firefox and see what version of Firebug you're running. If it's anything other than 1.2.0bX (where X is a number 1-15) you'll need to forcefully go to the above Firebug URLs and install the new version (the auto-update isn't working for older versions). The most common report of Firebug problems has been related to running Firebug 1.1 in Firefox 3 - which is a mess (hence Firebug 1.2).
Quality Improvements.
The Script panel (the JavaScript debugger), the Net panel (network monitoring), and Console panel have all seen considerable updates. They're all much more performant and have a huge number of bug fixes.
Specifically the Console panel has seen a number of security improvements. We'll be discussing the specific nature of these changes once everyone has had enough time to upgrade to Firebug 1.2.
A list of all the bug fixes can be found in the full release notes.
Selective Panel Enablement.
This is the most drastic UI change of the release. It's also a, seemingly, bizarre addition to the extension. When you now click Firebug for a site you'll encounter an interface that looks something like this:
Some back story is needed in order to explain why the extension is now set up in this manner. These three panels (Console, Script, Net) have the potential to incur a great deal of overhead into any web sites that utilizes them. There are two pain points, in particular: The Mozilla JavaScript debugger and network monitoring.
The Mozilla JavaScript debugger is used in two ways in Firebug: First it is used in the Script panel (to debug JavaScript code, naturally), second it is used to figure out where JavaScript errors are coming from in the console. Network monitoring is, naturally, used for the Net panel.
Here's the important point: The Mozilla JavaScript debugger and network monitoring are both global to Firefox not localized to a single window or tab. This means that when you enable a panel, such as the script panel, it will turn on the JavaScript debugger for all JavaScript code in Firefox.
Rob Campbell has run some initial numbers and has found that, simply, enabling the script panel anywhere in the browser immediately slows down all JavaScript execution by 25% - for all JavaScript on all tabs in the browser.
We don't have solid numbers on the networking monitoring overhead yet but we imagine it to be much less, although still occurring on a global all-tabs scale which isn't desirable.
The important question here is: What is being done to stop this?
First, it must become necessary to not incur any overhead when using the console panel. This is a ubiquitous part of Firebug and any global overhead presented by it must be removed. This can be done but not without some internal API changes to how Firefox handles and reports error messages. We hope to have something introduced in an upcoming version of Firefox so that we can compensate appropriately in Firebug.
Second, the JavaScript debugger must be improved. A number of bugs have been filed on this subject and we hope that some of them will make their way into upcoming versions of Firefox (Firebug will be able to immediately improve when that happens). Specializing the debugger to only work against a single tab at a time may not be possible (based upon how Firefox works, internally) but if it is that will be an immediate benefit. Of course, any performance improvements to the debugger will always be helpful.
Finally, the overhead of network monitoring (if there really is that much - we haven't run performance analysis her yet) needs to be diminished in any way possible.
All of these things are points that the new Mozilla Firebug team is trying to tackle for the upcoming Firebug 1.3 release.
Who enabled me?
Taking in to consideration the above performance points (namely the fact that enabling the Console, Script, or Net panels have the potential to incur a global overhead on all browser tabs) a feature was added to help you minimize your use of the panels in errant tabs.
If you position your mouse over the Firebug icon, in the Firefox tray, a tooltip will pop up telling you two things: The version of Firebug that you're using and which tabs have some Firebug panels enabled in them.
It should be noted that the Firebug will be a gray color if no tabs currently have a Firebug panel enabled at all.
Using the above tooltip you can now go in and selectively disable any panel usage that you are no longer utilizing.
Suspend/Resume Firebug.
Of course, when using the above tooltip (or seeing that the Firebug icon is lit up), you'll just want to suspend all use of Firebug panels straight out without having to poke-around each individual tab.
A new Suspend/Resume menu option has been added that will suspend/resume all active panels. This is a one-click way to keep Firebug in check.
So what's next for Firebug? I discussed some of the performance auditing that we were doing recently and that will be continuing.
Specifically, however, we plan on releasing some minor updates to Firebug 1.2 to quell bugs and improve performance (there will likely be a 1.2.1 release coming soon).
As I mentioned before, Firebug 1.3 is going to be all about performance, quality, and testing. Firebug is the de facto tool for web developers and we need to make sure that its quality does not wane and that we tackle performance head-on (with the eventual goal of having a seamless web development experience).
Tags: firebug, mozilla
53 Comments on 'Firebug 1.2 Released'
August 22nd, 2008
I've been waiting to blog about this for a long time now. A fantastic new improvement to Mozilla's JavaScript engine (SpiderMonkey) has landed. Code-named TraceMonkey this engine utilizes a techniques, called trace trees (PDF), which adds just-in-time native code compilation to SpiderMonkey.
A major goal of the project has been to set JavaScript up to compete with natively-compiled code, rather than simply against other interpreters. This means that we're starting to see speeds that are completely out of this league when it comes to performance.
Results and Try it Yourself
Here are the results from four benchmarks to give you a taste:

(Graph courtesy of Brendan Eich.)
The tests are:
If you want to try these out for yourself, just snag a nightly of Firefox 3.1, open about:config, and set the following preference to true:
javascript.options.jit.content
You should be, happily, in just-in-time tracing land. It's still buggy (hence the reason for hiding behind the preference wall) but it should be good enough to handle most web sites.
What's especially exciting is that this code is working on x86, x86-64, and ARM - which means that these improvements won't be limited to just the desktop - you'll be able to receive them on your mobile devices as well.
How Tracing Works
In simple terms tracing works by watching for commonly-repeated actions (such as loops, function calls, or type checking) and tries to optimize their resulting native code into the lowest number of actions. The premise is rather simple - and it's an advance that we'll probably see proliferate to many interpreters and engines in the upcoming years.
Andreas Gal published a paper (PDF) on the subject and Brendan Eich has written up a TraceMonkey-specific explanation.
Some of the improvements made by tracing include:
- Function Inlining: Removing the overhead of function calls by simply replacing them with their resulting native code.
- Type Inference: Removing checks surrounding common operators (like "+") when the types contained within a variable are already known. This means that the engine will have already pre-determined, for example, that two strings need to be concated when it sees the "+" operator.
- Looping: The overhead of looping has been grossly diminished. It's one of the most common areas of overhead in JavaScript applications (common repetition of a task) and the constant determining of bounds and the resulting inner code is made negligible.
The code for this project has come from a number of places - one of which is coming from some code contributed to Mozilla, from Adobe: Tamarin Tracing, specifically the nanojit code that's able to work a lot of this just-in-time magic.
Development
The work began just about 60 days ago, working with Andreas Gal of UC Irvine, to integrate the nanojit technology into Spidermonkey. You can hear more about the development from those that were involved: Andreas Gal, Mike Shaver, and Brendan Eich.
The full code can be found in the TraceMonkey mercurial repository (the commit to merge TraceMonkey into Mozilla core is massive, clocking in at about 4MB).
If you want to try running your own copy of TraceMonkey on the command-line, just follow these steps:
hg clone http://hg.mozilla.org/tracemonkey/
cd tracemonkey/js/src
make -f Makefile.ref BUILD_OPT=1
Darwin_OPT.OBJ/js -j
(The above assumes that you already have Mercurial installed, and are trying to compile on OS X. Your milage may vary. The -j option is what enables jit-ing on the command-line.)
There is still a ton of work to be done. The incredible speed-ups that we're seeing are only just the beginning. A lot can be done to improve how registers are currently being allocated which will provide even more speed-ups.
Right now there isn't any tracing being done into DOM methods (only across pure-JavaScript objects) - but that is something that will be rectified. Being able to trace through a DOM method would successfully speed up, not only, math and object-intensive applications (as it does now) but also regular DOM manipulation and property access.
Ramification
So what does this all mean? It means that JavaScript is no longer confined by the previously-challenging resource of processing power. With this improvement it's leap-frogged any sort of traditional and has gone head-to-head with computationally-powerful languages like C.
I fully expect to see more, massive, projects being written in JavaScript. Projects that expect the performance gains that we're starting to see. Applications that are number-heavy (like image manipulation) or object-heavy (like relational object structures).
One area that I'm especially excited about is in relation to Canvas. The primary thing holding back most extensive Canvas development hasn't been rendering - but the processor limitations of the language (performing the challenging mathematical operations related to vectors, matrices, or collision detection). I expect this area to absolutely explode after the release of Firefox 3.1 as we start to see this work take hold.
Seeing releases like this are absolutely exciting for me. JavaScript is absolutely the little-language-that-could - continually routing around any of its short-comings and blowing away all of its expectations. I look forward to using it for many, many, years to come.
Tags: javascript, firefox, mozilla, tracemonkey
77 Comments on 'TraceMonkey'
August 20th, 2008
A brand-new implementation of the Selectors API has landed in the latest Firefox nightlies (and in Firefox 3.1a1) - on track to head your way in the upcoming Firefox 3.1 release.
I've talked about this API before (1, 2) and while I do have some misgivings about the current API (which will be remedied in upcoming revisions of the spec) there is one thing that is undeniable about it: It is extraordinarily fast.
Thankfully, implementations haven't scarified specification compatibility for performance and we can see both the Firefox and WebKit implementations coming in at 99.3% passing the Selectors API test suite. Opera is working on their implementations, slated for Opera 10, and Microsoft has an implementation in beta 1 of Internet Explorer 8. This means that by late this year all browsers will have an implementation of the Selectors API in the market.
JavaScript libraries have already been working to utilize this new API, preparing for when it'll eventually be ready for all to use. The current score is:
- Dojo has querySelectorAll support in Dojo 1.1.1, although support for Safari 3.1 is disabled (there were troublesome crashing bugs in early versions of Safari 3.1 that have since been resolved).
- Prototype has querySelectorAll support in their Git repository (presumably to be rolled into their next release).
- jQuery has querySelectorAll support in an experimental plugin (to land in the next release).
This has lead to some interesting numbers (utilizing the same testing techniques employed by the WebKit team):
| Library |
Time (ms) |
| Prototype 1.6.0.2 |
44677 |
| Prototype Git |
9914 (123% slower than native, 351% faster than DOM) |
| jQuery 1.2.6 |
35045 |
| jQuery 1.2.7 Plugin |
4731 (7% slower than native, 641% faster than DOM) |
| Dojo 1.0.2 |
20782 |
| Dojo 1.1.1 |
5669 (28% slower than native, 267% faster than DOM) |
| Native |
4441 |
That means that libraries that utilize querySelectorAll will be running 2-6x faster than their previous versions. This is already quite impressive.
There are two points to consider when using this API:
- That you need to try and keep the overhead on top of the querySelectorAll method as low as possible.
- That it becomes advantageous to avoid the querySelectorAll API in some extreme cases (for example, jQuery avoids it for #id queries, allowing it to go over 10x faster than querySelectorAll).
A lot of bare-bones selectors library implementations are going to look something like this:
function querySelectorAll(selector){
try {
return Array.prototype.slice.call(
document.querySelectorAll( selector ) );
} catch(e){}
return myOtherLibrary( selector );
}
Note two points: There's a try-catch block there to capture any syntax errors that are generated by querySelectorAll (syntax errors could be generated by APIs that the implementation doesn't understand - like jQuery's div:first, for example). If no exception is thrown while retrieving the results we need to convert it into an array (most libraries convert result sets into arrays - or bless them in some manner).
Tackling both of these points will introduce some level of overhead in a library (on top of the native querySelectorAll implementation). Of course it's never as simple as it should be, many libraries extend these return sets with additional functionality so the overhead will be that much greater.
Regardless it's readily apparent that this API will be quite instrumental in trivializing one of the most difficult parts of implementing a new JavaScript library. Everything after this is just gravy.
Tags: mozilla, javascript, jquery, selectors, firefox
20 Comments on 'querySelectorAll in Firefox 3.1'
August 14th, 2008
Historically one JavaScript property that's seen a lot of use (mostly due to its convenience) is that of __proto__. It's a quick-and-dirty way of accessing the original prototype property of the object's constructor function. For example, the following is true:
"test".__proto__ === String.
prototype
// Another alternative, not using __proto__
// Only works when constructor isn't changed
"test".constructor.prototype === String.prototype
This feature has been codified in the upcoming ECMAScript 3.1 specification as a new method: Object.getPrototypeOf(object) (and is implemented in the latest Firefox nightlies).
So how can we make use of this, now standardized, functionality?
instanceOf
If you wish you could implement your own version of the instanceof operator, using pure JavaScript.
function instanceOf(object, constructor
) {
while (object !=
null) {
if (object == constructor.
prototype)
return true;
object = Object.
getPrototypeOf(object
);
}
return false;
}
instanceOf("test", String);
instanceOf(true, Boolean);
In this example we traverse up the prototype chain, checking each constructor along the way. It's an effective method and allows for great expressiveness in our code.
Super Methods
We could use this function to call a super method, while doing some inheritance.
function Person
(){}
Person.prototype.kick = function(type){
alert(type + " kick!");
}
function Norris(){}
// Inherit properties from Person
Norris.prototype = new Person();
Norris.prototype.kick = function(){
Object.getPrototypeOf(this).kick("Roundhouse");
};
In the above code we use Object.getPrototypeOf(this) to tap in to the original, inherited, kick method. Since we have since overridden the method we don't have direct access to it, but using getPrototypeOf we can capture, and utilize, it again.
Cross-Browser Implementation
The obvious question now becomes: How do we begin using Object.getPrototypeOf today if most browsers don't have it implemented yet? In the meantime we can use something like the following code for some form of compatibility:
if ( typeof Object.getPrototypeOf !== "function" ) {
if ( typeof "test".__proto__ === "object" ) {
Object.getPrototypeOf = function(object){
return object.__proto__;
};
} else {
Object.getPrototypeOf = function(object){
// May break if the constructor has been tampered with
return object.constructor.prototype;
};
}
}
While it's not 100% spot-on (since the .constructor property is mutable on any object - it's fully possible that it could've been manipulated by the user at some point) the above code should serve as a "good enough" solution to tide you over until browsers have good ECMAScript 3.1 compatibility.
Why Object.getPrototypeOf?
A common question at this point (and one that's sure to come up often as new features start to trickle in from ECMAScript 3.1): Why is the method Object.getPrototypeOf("test") and not "test".getPrototypeOf() - or even just a property, like __proto__? While having a method, or property, on every object would certainly be more convenient to use it ends up being impractical for generalized use.
For example, take the following case into consideration:
var obj = { getPrototypeOf: "blah" };
Any attempt to call its getPrototypeOf method would end in failure, forcing the developer to always have to fall back to using the generalized Object.getPrototypeOf. Since most uses of getPrototypeOf would be required to work in the general case the fallback would always have to be used. Thus it's not necessary to include it as an extra property of every object.
Additionally, it makes it far easier to backport to old implementations since you no longer have to extend the Object prototype (Object.prototype.getPrototypeOf = ...;) which would've been bad in any case.
Tags: javascript, mozilla, ecmascript
17 Comments on 'Object.getPrototypeOf'
August 13th, 2008
For the upcoming Firefox 3.1 release a lot of work has been going into improving its CSS support (specifically, in relation to the CSS 3 specification).
One areas that have received solid implementations is that of border-image. This is a new CSS 3 module that makes the exact slicing of images (and their positioning around an element) quite easy.
The most obvious use case for them exists in constructing beautiful scalable buttons. And there is, perhaps, no better use case than the one provided by the iui library: replicating portions of the iPhone user interface in a pure-CSS manner.
Here are two examples from the iui library (slightly tweaked to support both WebKit's and Mozilla's implementations of border-image).
You will need a nightly release of Firefox in order to have the following demos work properly.
The button on the top right ("Search") is mostly implemented using the following CSS:
border-width: 0 5 0 5;
-webkit-border-image: url(toolButton.png) 0 5 0 5 stretch stretch;
-moz-border-image: url(toolButton.png) 0 5 0 5 stretch stretch;
With toolButton.png looking like:

The premise behind border-image is complex, but easy to learn. When used in the manner shown above you are, effectively, providing slice offsets into the provided image - telling the browser how to position the slices.
For example the 5s in the border-width and border-image indicate that there should be a 5px-wide border on the left and right of the button. The contents of the border should be populated with the left and right-most 5 pixels from toolButton.png. Since a horizontal border width value is provided it is possible to scale the contents of the button horizontally (inserting more contents will allow it to continue to work properly).
The 0s, on the other hand, indicate that entirety of the button background should be consumed by toolButton.png - and that none of it should be used to show the border (border-image can be used as a crude mechanism for injecting background images). Because of this the image won't be able to gracefully scale vertically.
CSS3.info provides another example that shows how the stretching and rounding work.
with the following base image:

Rounding:

Stretching:

By tweaking the stretching of the border-image you can end up with some truly-compelling results.
We can see another one in a second iui button:

With the following CSS being used:
-webkit-border-image: url(whiteButton.png) 0 12 0 12 stretch stretch;
-moz-border-image: url(whiteButton.png) 0 12 0 12 stretch stretch;
together with this base image:

border-image has a large number of compelling use cases. It's fantastic to see some coordinated efforts by browser vendors to make their implementations common-place.
Tags: mozilla, css3, css, firefox
21 Comments on 'border-image in Firefox'
August 12th, 2008
Firebug 1.2 final is set to be released sometime within the next week or two which means that our goals for Firebug 1.3 need to be pretty clear at this point. Last week the Firebug Working Group convened at Google to discuss the goals for the upcoming release. In taking a step back and looking at what was most important one thing was quite obvious: The stability and performance of Firebug needs to be improved.
Unfortunately we're in a very difficult situation. There are, approximately, three developers who've done any sort of serious bug fixing on the internals of Firebug. One is John J. Barton (of IBM - primarily responsible for the 1.1 and 1.2 release of Firebug) and the other is Jan Odvarko (of Mozilla - part of the new Firebug team). Unfortunately the primary source of information lies in Joe Hewitt (the original creator of Firebug), who is quite incommunicado these days.
There are a few areas in which we (and, specifically, the Mozilla Firebug team) need to work in order to gain a solid footing.
Improve the knowledge of Firebug that we have.
Right now information about Firebug internals are quite limited. Not only does there need to be some serious overviews of what's there but inline documentation needs to be improved as well. It can be incredibly hard to hack your way around some aspects of the code base, especially when it isn't obvious how something works.
We're going to be working two-fold in this area: To start Rob Campbell and I will be working on some Firebug extensions in order to get a better feel for the code base - and secondly we will, as we go, write up tutorials and documentation for what we find.
Jan has already written up an excellent series of tutorials that explain how to construct Firebug extensions. They're, already, quite valuable.
Build a runnable set of test cases to prevent regressions.
The unit testing (or, really, any testing) situation in Firebug is quite abysmal. Features have gotten accidentally removed from releases simply because they weren't immediately apparent that they existed. We need to make sure of two things: 1) That existing features don't break or get accidentally removed and 2) That a good enough coverage of the internals is in place to support future development.
Since there is a considerable amount of traffic through the code base (developers contributing patches, multiple developers handling different modules - all over some 35,000 lines of JavaScript code) some form of diligence needs to be provided in order to prevent errors from slipping through.
Track the state of Firebug performance.
There's, effectively, no picture of how Firebug is currently performing (or, more accurately, hindering performance) in Firefox. If we want to improve the quality of the code we have to have a clear picture of which areas are problematic. This is one area in which Mozilla's resources can be especially beneficial.
In Mozilla there is a system called Talos which is used to create builds of Firefox (for all the various branches - right now we're testing Firefox 2, Firefox 3, and Firefox 3.1) and run them against sets of performance tests. The tests consist of page rendering performance, CPU usage tracking, memory usage tracking, JavaScript performance, browser start-up time, graphics rendering, and on and on.
A sample chart - showing page loading performance on Windows XP (a ton more can be found here):
We want to create some builds of Firefox that have Firebug on in various states. For example: Firebug installed (but disabled), Firebug enabled, Firebug with console enabled, Firebug with debugger enabled, Firebug with network monitoring enabled, etc. With all these permutations we'll be able to get an exact number for how much overhead current Firebug code is providing and where we can start to make necessary improvements.
Audit and Improve.
Finally, once we have some documentation about the structure, a test suite running, and nightly performance numbers being generated we can really start to dig in and make improvements. It's going to be slow-going at first but laying this groundwork will make for an effective use of our time (increasing the likelihood that other people will be able to help contribute to the codebase, as well). If we can have a stable and fast Firebug 1.3 ready in time for Firefox 3.1 (which is due out this fall/winter) then I feel like we will have made some good headway and started to serve our purpose well.
Tags: firebug, mozilla
14 Comments on 'Tracking Firebug Performance'
July 17th, 2008
I've got a mini-announcement. Starting this week about half of my time at Mozilla is going to be spent driving the direction of the brand-new Mozilla Firebug team. I'm, understandably, quite excited about this proposition. Like all web developers I've found Firebug to be an invaluable tool for web development.
We have a great team forming - I'm going to be joined by:
We're in a very primordial stage right now - we're meeting at the Firefox Summit at the end of the month and again at the beginning of August for the Firebug Working Group. We'll be setting some major goals for post-Firebug 1.2 development. I highly suspect that we'll be doing some exploratory Firebug extension development as well.
In the meantime we'll be hanging out in the Firebug IRC channel, which can be found here:
Server: irc.mozilla.org
Room: #firebug
We're going to love to hear any suggestions for feature development - I'm sure you've got tons of ideas - and we do as well. I'm quite excited about all of this. Here's to a bright Firebug future!
Tags: firebug, firefox, mozilla
75 Comments on 'Firebuggin''
·
« Previous entries