Something that jumped at me, recently, was a rendering dilemma that browsers have to encounter, and gracefully handle, on a day-by-day basis with little, to no, standardization.
Take the following page for example. You have 4 floated divs, each with a width of 25%, contained within a parent div of width 50px. Here's the question: How wide are each of the divs?
The problem lies in the fact that each div should be, approximately, 12.5px wide and since technology isn't at a level where we can start rendering at the sub-pixel level we tend to have to round off the number. The problem then becomes: Which way do you round the number? Up, down, or a mixture of the two? I think the results will surprise you, as they did me.
Opera 9
Safari 3
IE 6
IE 7
Firefox 3
Firefox 2
We have three completely different camps here:
Round the numbers down - Both Opera and Safari round down the widths of all the divs to 12px. This leaves a 2px gap (note the green) to the right of all the divs. If you've ever wondered why your nicely-aligned navigation doesn't fill up the full contents of a container in these browsers, now you know why. On the plus side, at least you know what the width of these containers will all be the same, no matter what.
Round the numbers up - Both Internet Explorer 6 and 7 round the widths of all the divs up to 13px. Doing this causes the floated divs to immediately wrap, breaking layouts. This is obviously wrong as it causes many safely-numbered layouts to break for no obvious reason.
Round some numbers up and some down - Both Firefox 2 and 3 mix the rounding of the div widths to 12px and 13px. The mix of rounding is done as to provide an even result at the end (making it flush with the far edge). The obvious side effect is that the divs no longer have a consistent width to them (even though an equal width was specified by the CSS). Additionally, the reported (via a JavaScript computed style call, like offsetWidth) width of the element remains at its reported 12.5px not providing the user with any indication of which way the rounding is occurring. And to add another confusing wrench in the works: The order of which divs have a width of 13px or 12px has been flip-flopped in Firefox 3. This was done to improve efficiency and speed and seemingly little, to no, effect on general web site rendering.
I was talking this over with some Mozilla developers and David Baron explained the situation quite well:
We're trying to meet a bunch of constraints that can't all be satisfied at the same time (the proof is left as an exercise to the reader, though I may have actually written it out once in a Bugzilla comment):
1. 4 adjacent objects of width/height 25% (for example) starting at one edge of a container should end exactly at the other edge; there should never be an extra pixel in the container and they should never be wrapped due to being a pixel to wide
2. objects that are logically adjacent should always touch visually; there should never be a pixel gap or a pixel of overlap due to rounding error
3. objects given the same width should occupy the same number of pixels
4. object boundaries should always (visually) be aliased to a specific pixel boundary in the display (they should never be blurred)
The one [Mozilla] sacrifices is typically (3), except for borders where we sacrifice (1) by rounding the widths to pixel boundaries much earlier.
The especially strange part, in all of this, is that there's really no right, or wrong, here. How this behavior is supposed to play out by the rendering engine isn't dictated by the CSS specification, having it be left up to the implementation to render as it sees fit. Obviously the four guidelines outlined by David, above, could serve browsers well but they are forced to sacrifice at least one of them in order to meet most of them.
The whole situation is quite fuzzy and frustrating - I'm not sure what the best action is, moving forward, but at the very least it's in the open now where we can think about it some more.
Looking ahead a little bit: At the start of 2009, will JavaScript-based memory leaks still be relevant? Will onunload event handler cleanups still be required?
I'm fully willing to submit that they'll be around for a long time, in one form or another - but just how long? One year? Two? Three? IE 5 is at < 2% and no major JavaScript library supports it. I suspect that we might have to wait until that level before people start to chop off IE6-with-JScript-5.6 support.
Think about it: A year ago the world of Safari was pretty grim, but they gave us Safari 3 and it helped to clear things up significantly. Right now timers can be frustrating in Firefox 2, but Firefox 3 is giving some serious love to clean things up. It definitely appears as if the IE team is becoming serious about moving forward, so what can we expect here?
As I start working on my next book I have to ask questions like this. If I write about memory leaks will it even matter by the time the book is published? (Not saying that the book won't happen until 2009, but that's probably when it'll be on most bookshelves.) Memory management will always be an issue, but memory leaks (as we know them) are surely doomed - it's just the time frame that is unclear. Regardless, I think there should probably be a web-only article on memory leaks, I'm just not convinced that it should be in the book, proper.
A big push of Firefox 3 has been to improve its overall performance (memory, speed, ui responsiveness, JavaScript, etc.). One thing that I wanted to see get a little love was the performance of timers (setTimeout and setInterval). However, in order to make my case, I had to do some analysis.
I built a super-simple test case: Moving a div, one pixel at a time, 100 pixels. I did this using setTimeout, setInterval, and using Mozilla's internal nsITimer interface. I wanted to try and get an accurate reading on a couple things:
How long of a delay is there between timer calls?
How much fluctuation is there on timer calls?
How well do multiple simultaneous timers scale?
What is the minimum delay achievable with a timer?
Key: The horizontal axis is the recursion depth of the timer call, vertical axis is the actual delay between the timer calls - in milliseconds, and the line numbers correspond to the number of simultaneous timers being called.
The graphs are organized as such: (From top left, going clockwise) Firefox 2, Safari 3, Opera 9, Firefox 3.
Modified Firefox 3: Now, after having run all of those tests, I went through and commented out the timer filtering code in Firefox to see what the results would be. View full results (from left-to-right, nsITimer, setInterval, setTimeout, top-to-bottom 0ms, 10ms, 20ms delays).
Conclusions (OSX-only)
WebKit's timer code is the thing of dreams. Their results are as smooth as a baby's bottom. Simply incredible.
Opera is really messy - all over the place in its tests.
Firefox 2 is generally pretty stabilized, but has nasty spikes in delay (from where the garbage collector kicks in).
Firefox 3 has less nasty, long, delays - but has weird dips down to 0-2ms (this should probably be looked into).
Firefox 2, Opera, and Safari all have a bottom window of 10ms for delays - Firefox 3 is now 15ms, for some reason (this should probably be looked into).
Once you start moving into the range of 64-128 simultaneous timers, you're pretty much out of luck in most browsers.
nsITimer can't be beat (for speed) with 1-2 simultaneous timers.
There's something really wrong with nsITimer in Firefox 3.
Removing the timer filtering code (in Firefox 3) reveals that there's a significant amount of timer logic located in the DOM code - as opposed to the pure timer code.
As noted above, these tests were run on OSX only. If anyone is interested in producing some results from Internet Explorer, Firefox 2, Firefox 3, and Opera, you're welcome to it. In the meantime, Vlad produced some basic results from Firefox 3 on Windows XP (setTimeout, setInterval, and nsITimer). Note how different they look from the OSX results. It may be a safe bet that some of the above results, and conclusions, may be localized to just the OSX platform.
I'm hoping to spawn some discussion from this, to better figure out which of these issues are actually bugs and need to be resolved (in particular, in Firefox 3). Don't worry, Webkit team, you guys are completely off-the-hook.
The other day I caught this humorous image posted to Reddit, showing a Firefox update dialog popping up over a weather satellite image, live on TV:
I was amused, so I posted it to one of Mozilla's internal mailing lists - which started a renewed flurry of discussion surrounding the update manager. To start with, a bug was filed on this specific issue: don't prompt for software update unless firefox is the foreground application. Second, it was pointed out that a particular fix has already landed in Firefox 3, related to this issue: Software update dialog steals focus / wait for idle before prompting. Obviously, that's a good thing, but only the first step. So in addition to not prompting when the dialog is in the background we now, additionally, have the following bugs which are desired to be resolved:
Needless to say, this particular issue, while haphazardly amusing, will no longer be a problem in Firefox 3.
One thing that I find to be particularly interesting about this whole situation: The easier, and less painful, it is for a user to upgrade minor releases of Firefox, the more secure the browser is. (If a fix is released for a security problem and the user opts to not upgrade, they choose to remain vulnerable - which is a very bad thing.) Thus, anything that can be done to improve the quality of upgrading is considered to be a security enhancement. Security through improved user experience! I like it.
Prior to the release of Firefox 2.0.0.10 a minor security issue was discovered in the drawImage method in the Canvas API. This particular method takes an image (in the form of an IMG DOM Element), extracts the image data, and puts it into the Canvas at the desired points. If you're interested in seeing what this method does (and aren't running 2.0.0.10) then visit the Mozilla developer demo. The issue was that if the image was corrupted in some way, drawImage would still try to read data from it and display random bits of memory instead (oops).
This was fixed and two attachments were uploaded resolving this bug. However, that's where the issue came in. When it came time to commit the changes, only the first patch landed (by mistake) which caused drawImage to become all wonky. Coupled by the fact that there wasn't an immediate regression test in place to notice the obvious error. (That being said, we're getting much better - going from very few automated tests about a year ago, to tens of thousands now.)
The obvious bug is spotted and the patch is landed. The question then became: How serious is this? In a nutshell: Very serious. A number of critical applications were using this functionality to draw parts of their UIs and having this fail made them unusable. Thus, the new question was: How fast can we get it out? The answer:
Nov. 29: Firefox 2.0.0.11 is released, fastest turnaround for a browser, yet.
So that's why you're seeing two browser updates in one week. It was a big mistake, but thankfully it was caught quickly, fixed quickly, and released quickly. And in the end, it'll be a good thing, as I'm sure it'll get some more regression tests landed in the suite.
It's a full map detailing everything that exists within the world of ECMAScript (with JavaScript, ActionScript, and JScript being its most-famous implementations). Right now I'm only showing things that can be built on top of (languages, engines, browsers, servers, etc.) - not end user applications (there would probably be too many to list).
This chart started out as a simple diagram showing the relationship between ActionScript, Tamarin, ActionMonkey, and SpiderMonkey. From there I started tacking on additional relationships and it just sort of started to grow out of control. I'm fascinated by the size and breadth of everything in that exists in the ECMAScript ecosystem (and this isn't even everything, I'm sure I'm missing a ton).
Let me know if there's anything that you feel that I've missed. I'll use my discretion when adding, simply because I don't want this to include every half-baked ECMAScript implementation under the sun (and I still have to modify it by hand).
Update 3am Nov. 15: Removed WebKit (was redundant), added Silverlight, added IronPython and IronRuby, connected PDF to SpiderMonkey, and fixed spelling of Konqueror. Presto is wrong for Opera, but not sure what their JS Engine is named. Compressed PNGs, added an SVG download.
Update 5pm Nov. 15: Turned JavaScript into a language/cloud. Added ParenScript, YHC/JavaScript, Haxe, and Scheme2JS. Added CouchDB. Silverlight now links to JScript. Opera's two engines (futhark and linear_b) are listed. Added Flex. Changed QSA to QT Toolkit.
The other week I went to the Boston iPhone Tech Talk and took a bunch of notes. I thought everyone would be interested in what they had to say as its quite relevant to Mozilla's upcoming mobile efforts, and the browser space in general. Let me know if anything needs any, additional, clarification.
Notes:
There was a lot of JavaScript hate by attendees ("blah blah... GWT is the only thing we trust... blah blah JavaScript is a stupid language..."). Not really surprised. Generally, these are Mac application developers by trade and the Open Web, by comparison, is frustrating and limiting.
There was strong promotion of web standards, down play of plugin (Flash, Silverlight, Java Applets) dependencies.
They recommended optimizing your page according to the following points: Scales for readability, minimize pan/zoom, finger friendly, and tuned for wireless. That translates to: Use clear type and logical page layout, reduce the height or width of the page to better fit within the screen, make your links and inputs large (to handle the large "mouse pointer"), and make liberal use of caching and gzip. All of these are good points to encourage within the web, in general.
Pages that are marked up with XHTML Mobile or are on a .mobi domain are handled specially (they're shown unmodified - assuming that the developer has already optimized the page for a mobile device appropriately).
There are some, very interesting, limitations to pages; and the browser, in general. For the most part this shouldn't effect many sites (especially considering that plugins don't run). I've noted the JavaScript-related ones:
10 MB JavaScript object allocation
5 second JavaScript execution limit
XHR not counted to JavaScript execution time (async or sync)
Scripts may be paused (Inactive window, Safari not active)
Scripts are not paused while a Quicktime movie is playing
Maximum 8 windows open at a time
I found it to be interesting that JavaScript execution was pausable. Thus, if have a game running in one window and go to another, the game (presumably, written in JavaScript) will be paused until you come back to it. This model is akin to what they currently do with Dashboard widgets (which are, also, HTML/CSS/JS and are paused until you view them).
It's important to note that, not only, are you not able to have more than 8 windows open at a time, but you don't have control over windows that you open. There is no such thing as a popup or modal dialog. Nor are there tabs to browse through the open windows (You have to navigate to a separate view where you browse thumbnail views of the sites). I've been trying to decide if this is more-tabbed-like or less-tabbed-like because of how it's designed (e.g. one could argue that having modal popups breaks the tabbed model), whereas not actually having access to tabs (or information about the tabs that you open) is very limiting.
Only three dialogs are allowed: alert, confirm, and prompt. They are all highly styled and consume a large portion of the screen when they appear.
Interacting with form controls is highly unique. When you do so you are placed into a separate editing/manipulation mode laid on top of the browser itself. This is indicative of the larger theme in the browser: They consistently push the user into a separate pane to deal with specialized content. I think that this is an incredibly interesting development and - quite possibly - an optimal way of dealing with "non-native" browser content.
For example, Excel, Word, PDF, and Quicktime content are all handled natively by the browser - and are shown in separate, specialized, views. (Videos are especially interesting - the whole browser is hidden and is replaced with a completely-tailored UI that is optimized for viewing movies.) I was hugely impressed by this set of features and I really think that this is a huge step for a browser to take. Mozilla is starting to do this with the new video tag, but providing means for handling common documents might be interesting as well.
They include a fully standards compliant version of Canvas - they recommend using it, highly. In fact, they recommend using things like border-image, border-radius, and Canvas to remove the need for extra markup or images.
There is no way to completely emulate the iPhone outside of the iPhone itself (e.g. no desktop iPhone browser - even though there's Webkit/Safari - it's not completely the same).
Webkit's new Element Inspector is very, very, nice. Heavily inspired by Firebug, but with the trademark Apple UI touch. They have a CSS/Stylesheet browser (like Firebug) but they also include the default User Agent Stylesheet (which is immensely useful).
To allow the user to have control over page scaling they define a custom meta name/content that you can use:
<meta name='viewport' content='width=320'/>
The possible values for it are as follows:
width=320 (how wide to start the viewport at)
initial-scale=1 (default dimensions)
minimum/maximum-scale (limits user/auto scaling)
user-scalable=yes/no (Allows/prevents zooming via double-taps)
When the user zooms in on a portion of the page, you can adjust how large/small the font size should become with a custom CSS property:
-webkit-text-size-adjust: none
none (font size doesn't grow larger)
auto (the text grows larger)
200%, the text grows even larger
They also publish their own, custom, event and window property to let the user know about the orientation to which the iPhone is rotated, it can be used like so:
There is no concept of hovering (or, really, mouse move events in general - drag/drap isn't possible).
There are no multiple selects. All multiple selects are just treated as single selects.
There is no way to detect which type of connection that you're on (Edge vs. Wireless) and to serve content based upon it. The one catch is that you're able to do it with Quicktime (serving different types of movies) but not with normal web content.
Finally, they're very interested in getting a public sync schema for bookmarks - one that works across all browsers (easily synchronizing Firefox with Safari with iPhone Safari, etc.). Apparently they've contacted Mozilla in the past about this, but I'm not sure to what end this has led.
This past Friday I gave my first Google Tech Talk on Building a JavaScript Library. I was invited to speak by Jon Wiley and had a chance to speak with a bunch of people on the User Experience team at Google (and, of course, try the always-popular food).
Based upon some of the questions that I got, it definitely seems like there's a market for a jQuery presentation, at Google. Maybe I'll be able to give another talk there someday - time will tell!
I'm glad that I've been able to start codifying my thoughts surrounding JavaScript Library design and implementation. We'll have to see where it leads (if it does lead anywhere besides a presentation) - maybe it'll end up in the form of a book or set of articles.
Please let me know if this talk interested you as I'm trying to gauge what interests other web developers - because all of this stuff fascinates me (JavaScript programming, open source projects, etc.).