Archive for January, 2010

Comparing Theora 1.1.1 with x264

Sunday, January 24th, 2010

There’s a comparison that I was pointed at today showing the difference between a number of different modern encoders. The Theora 1.1 demo on that page looked particularly bad, so I decided to investigate.

I downloaded and compiled the latest versions of libogg, libvorbis and libtheora from xiph.org. I ran the encoder example (as the other test did), but discovered that it does support two-pass encoding, contrary to what was stated on the other test’s page. I ran a few different two-pass encodes (including one with soft rates), but didn’t get a lot of variability between results. Overall, however, my newly re-encoded version is significantly better than the one on the other page.

It appears that the Theora 1.1 version is at least as good as the XviD encoding, but at a smaller bitrate. It’s not as crisp as x264, but I’m not sure I’d notice the difference.

Source (via saintdevelopment):

Theora 1.1 (2939kbps):

./encoder_example -o touhou.theora.ogg --two-pass -V 2931 stream.y4m

XviD (3127kbps,via saintdevelopment):

x264 (2951kbps, via saintdevelopment):

Just so it’s clear: all of the results on this page with the exception of the Theora 1.1.1 screenshot, are taken from Saint Development’s codec comparison. The images in the comparison are from frame 700 in the final video (extracted in PNG format using mplayer as described by the test).

It’s clear that a lot of people have stopped testing IE6

Monday, January 18th, 2010

IE6 has been getting a bad rap lately. France and Germany are both warning their citizens not to use it. The recent intrusions at Google were purported to be caused by holes in IE6. Even Microsoft is warning users to steer clear of it.

To get an idea of who’s given up on testing against this ancient browser, I’ve been running around browsing with IE6 in a VM. From what I’ve seen so far, it’s not getting a lot of love.

I’m pretty happy about this: as more and more sites break in IE6, it drives more people to browsers that don’t suck like Chrome or Firefox. It’s the last part of the browser death spiral: completely busted on the new and exciting sites.

The web browsing experience is pretty poor overall. Many sites serve transparent PNG files to the browser, which often render with miscolored backgrounds. Elements gain random padding, throwing nicely formatted designs for a loop. Other elements that are shrink-wrapped in other browsers sometimes end up with extremely large widths.

Note: I tried not to test sites too deeply- I figured that deeply nested screens will occasionally break in modern browsers too.

Facebook

Facebook is the first site I visited. I figured that this would be the site most likely to regularly test against IE6. It’s clear that they do some testing: the interface works reasonably well overall, with only a few small glitches that might annoy a user.

The most glaring issue happens when you click the “more” link on the left. The UI gets kicked down to the bottom of the screen. Looks like a classic IE float bug:

The setting popup menu occasionally gets itself into a state where it pops as you mouseover the popup part of it, becoming entirely useless (it also random gains padding from time to time):

Twitter

Twitter’s site is pretty simple, but it’s obviously not been tested in IE6. The CSS image sprites they use as controls on each tweet are totally busted:

Google Reader

Google reader is a rich application and works reasonably well in IE6. Lots of little formatting issues: buttons that are cut off, icons that float in the wrong place, stuff pushed down a line. Overall, still usable, albeit slow:

FriendFeed

FriendFeed’s audience is probably not using IE6 and I imagine that they don’t put a lot of work into testing it. Many of the sidebar links don’t work and it sends transparent PNGs to IE6, which happily poops all over them:

Brizzly

An up-and-coming Twitter client, Brizzly looks pretty stellar in modern browsers. The front page is a bit mangled in IE6, however:

When you try to log in, it’s pretty obvious that IE6 isn’t in their plans:

Final thoughts

There’s a pretty big part of the web that still works in IE6, but a lot of the popular sites are getting pretty buggy in IE6. If your startup decides that it’s not worth supporting IE6, I wouldn’t blame you. IE6 is rockin’ a 13% market share on StatCounter and it’ll likely drop down to 4-5% by the end of next year.

Is it worth all the trouble to support IE6 for me? It depends. I’m not going to worry about fixing every little visual glitch in IE6. I’ll probably start sending down transparent PNGs to everything, even if the images don’t look great in IE6. If some bit of functionality breaks in IE6, I’ll repair it to the point where it works well enough to get the job done.

Full support for IE6? No thanks.

3rd-Party Cookies, DOM Storage and Privacy

Wednesday, January 6th, 2010

We’re in the process of launching our new publisher integration feature at DotSpots and needed to gain an understanding of how browsers deal with “third-party cookies”, or cookies that are set on domains that differ from the top-level domain.

Each of the major browsers, Firefox, Chrome, Safari, Opera and Internet Explorer have their own quirks about how cookies are accepted, which vary wildly depending on whether they were set by a top-level page, or a page in a third-party iframe.

Executive summary: Based on this study of browsers, the ideal method of storing information in iframes is a combination of localStorage for modern browsers and persistent cookies with a privacy policy for downlevel IE and Firefox versions. The default privacy settings are permissive enough on most of the old browsers to make this approach feasible. Earlier Safari versions that don’t support localStorage are out-of-luck, but the market share is too small to worry about.

These are the browsers I tested:

  • Firefox Default (checked ‘accept third-party cookies’)
  • Firefox (unchecked ‘accept third-party cookies’)
  • Chrome Default (allow all cookies)
  • Chrome (accept cookies only from sites I visit)
  • Safari Default (only from sites I visit)
  • Safari (accept cookies always)
  • Opera Default (accept cookies)
  • Opera (only from the site I visit)
  • IE6 Default
  • IE7 Default
  • IE8 Default

All browsers that support localStorage support setting and retrieving storage values from any frame. This includes Firefox, Chrome, Safari and IE8. HTML5 localStorage is by far the most reliable way to store information at this time for browsers that support it. There is one small difference: in Firefox, blocking all cookies will also block localStorage. In Chrome and Safari, blocking cookies does not block localStorage.

Chrome and Safari are based on the same WebKit engine and, as expected, share the same cookie policies for the same modes. Chrome defaults to the more permissive ‘Allow all cookies’ setting, while Safari defaults to ‘Allow Cookies from Sites I Visit’. When third-party cookies are disabled, frames can read cookies set by top-level pages but not write them.

Firefox defaults to a permissive mode in which cookies can be set and retrieved from all locations. Unlike WebKit browsers, disallowing third-party cookies means that a third-party iframe cannot read or write cookies at all.

Opera also defaults to permissive mode. In “accept cookies only from the site I visit” mode, it behaves the same way as Firefox does when third-party cookies are disallowed.

Internet Explorer is a bit finicky about privacy. If you add a basic privacy policy header to your responses, cookies will be accepted from iframes. Without the policy, most cookies can’t be set or retrieved in iframes at all (the exception is that iframes can read session cookies set at the top level). The following P3P header is sufficient to fix cookies in iframes.

P3P: CP="CAO PSA OUR"

To configure the header in Apache, you can use a simple mod_header line:

        
Header append P3P "CP=\"CAO PSA OUR\""

For those interested, here is a breakdown of cookie handling by browser and mode. Unlike cookies, HTML5 localStorage has no known limitations, so it has been omitted from the following charts:

WebKit, Allow All Cookies (Chrome default):

Set / Can be read Top level Iframe
Top level X X
Iframe X X

WebKit, Only From Sites I Visit (Safari default):

Set / Can be read Top level Iframe
Top level X X
Iframe

Firefox, default:

Set / Can be read Top level Iframe
Top level X X
Iframe X X

Firefox, unchecked ‘accept third-party cookies’:

Set / Can be read Top level Iframe
Top level X
Iframe

Opera, default:

Set / Can be read Top level Iframe
Top level X X
Iframe X X

Opera, Only From Sites I Visit:

Set / Can be read Top level Iframe
Top level X
Iframe

IE6/IE7/IE8 default mode, without Privacy policy:

Set / Can be read Top level Iframe
Top level X *
Iframe

* session cookies set by the top-level page may be read by iframes, but persistent cookies may not

IE6/IE7/IE8 default mode, with Privacy policy:

Set / Can be read Top level Iframe
Top level X X
Iframe X X

Chrome for Mac has Extensions Again!

Wednesday, January 6th, 2010

It looks like the Chrome team has finally re-enabled extensions on Mac again (hat-tip to MG Siegler) in the latest dev channel build. You can’t update from the “About Google Chrome” screen yet, but you can grab the latest build and install it directly.

Even better, they are now allowing Mac users to install extensions directly from extension pages (warning: shameless self-promotion link).

Extensions are working well. They’ve turned on the browser action menus, so the various extensions that I’ve installed all work properly.

Bookmark sync is enabled as well, but I haven’t seen where the bookmarks are supposed to show up in Google Docs.

I’ve really missed having extensions for this last month; getting them back made my day!

More on window.name Cross-Domain Transports

Monday, January 4th, 2010

I previously discussed using window.name as a transport last year, but there wasn’t enough information and theory in the previous post to implement your own transport. I’ll fill in the gaps a bit more here to help developers looking to implement this themselves. You can also see the implementation we’re using at DotSpots in the gwt-rpc-plus project: Cross­Domain­Frame­Transport.java and Cross­Domain­Frame­Transport­Request.java.

The process of making a window.name request is described below. Note that you can inspect the HTML and HTTP traffic on my blog to see how our DotSpots plugin performs the cross-domain requests.

  1. Create the iframe and form to post. In IE, we use ActiveXObject as previously discussed to work around the machine-gun navigation sounds. You’ll need to stash a reference to the ActiveXObject somewhere where IE won’t garbage collect it.
    if ("ActiveXObject" in window) {
        var doc = new ActiveXObject("htmlfile");
        doc.open();
        doc.write("<html><body><iframe id='iframe'></iframe></body></html>");
        doc.close();
        var iframe = doc.getElementById('iframe');
    } else {
        var doc = document;
        var iframe = doc.createElement('iframe');
        doc.body.appendChild(iframe);
    }
    
    var form = doc.createElement('form');
    doc.body.appendChild(form);
    
  2. Set the the iframe’s name to a globally unique request ID. Using a unique request ID is very important, as two frames with the same name in Safari will result in one of them being set to a random name.
    iframe.contentWindow.name = requestId;
    form.target = requestId;
  3. POST the form to the endpoint, including the unique request ID and URL on the host domain. You can usually use /favicon.ico as a local path to return to. This is what gets posted by the DotSpots plugin on my blog:
    serial=0-8908858
    data=... (truncated JSON data)
    type=window.name
    redirect=http%3A%2F%2Fgrack.com%2Ffavicon.ico
  4. At this point, the iframe is now in a different security domain, so onload events won’t fire and window name is inaccessible.
  5. The server generates code to set the window name and redirect back to the original domain. Since the iframe is in a different security domain, the parent page won’t be able to tell that it was loaded. We redirect this iframe back to the URL requested once we’ve set the name.
    <html><body>
    <script>
    window.name='wnr-0-8908858(truncated JSON data)';
    window.location.replace('http://grack.com/favicon.ico');
    </script></body></html>
  6. The browser redirects back. When it gets back to the other domain’s favicon, onload will successfully fire and the window.name previously set by the server will be accessible. As multiple onload and onreadystatechange events might occur during the request/response process, you should always check the window.name for the appropriate prefix.
  7. Clean up the iframe and form. Remove the iframe and form after the request completes, but do this after a short delay. If you remove the iframe immediately after onload fires, the Firefox loading throbber will continue to animate indefinitely.

If you are considering using a transport like this for your own project, you should also consider using postMessage for uplevel browsers that support it. There are two HTTP requests required for window.name, adding a fair bit of latency to each cross-domain request. Using postMessage reduces the number of requests to one, cutting the round-trip latency by 50%.

Your server responses when using postMessage should look like this instead:

<html><body>
<script>
window.parent.postMessage('wnr-0-8908858(truncated JSON data)', '*');
</script></body></html>

If you’re using GWT, all of this work is already done for you in our open-source library, gwt-rpc-plus. We’ve tested it against all of the current desktop browsers (all the way back to IE6) and the mobile browsers too (Android and iPhone).

The Next Decade

Sunday, January 3rd, 2010

The last ten years have been a wild ride for this planet, but I’m sure the next ten are going to be even more exciting. I’d like to offer my predictions of what we’ll see around now, ten years in the future.

The browser will continue its domination in the world of applications, absorbing more of what we do in desktop applications. A significant fraction of software development will happen in the browser, though most development will still happen on the desktop. WebGL will be starting to become a major platform for gaming. IE6 will be a war story told by greybeard developers, Microsoft having jumped back into the browser race and caught up to the leaders of the pack. No single browser will have a majority share worldwide. Javascript will still be the biggest language, but it will have gone through a few language iterations. The browser JS VM will be near the speed of native code, less than 25% slower.

Devices will continue to double in capacity and speed every few years. In 2020 you won’t have a desktop computer. You’ll have something in the form-factor of a laptop or tablet that you dock and charge wirelessly wherever you device to work. Hard-drives as we know them today won’t exist in most machines, replaced by various forms of multi-terabyte solid-state storage.

You’ll be carrying around a mini-computer in your pocket that runs at the equivalent speed of today’s MacBook Pro. It’ll multitask easily with a few GB of RAM and have nearly a terabyte of solid-state storage onboard. The mobile experience will be a scaled-down, synchronized version of your larger machine rather than an entirely separate device. In fact, some people may eschew the larger device and hook their mobile device wirelessly into display and input devices when they want an easier environment to work in.

Your phone and laptop will have high-end cameras with thin liquid lenses that will be good enough for most people to stop carrying around dedicated point-and-shoot cameras.

E-books will continue to grow, but the functionality will move out of dedicated devices and into portable computers with improved screens that work as well as e-paper today. Electronic textbooks will have taken over the majority share of post-secondary education and will start to make inroads in earlier school grades.

Land-lines will be a legacy technology in 2020. Most people will opt to forward their personal cell phones to an adapter that rings a home number as well when the phone is nearby. Telcos will start offering a much-higher-fidelity audio codec for cell phones that offers VoIP-quality conversations.

True electronic commerce will be starting to emerge in 2020, replacing wallets with your electronic devices for power users. Instead of carrying around a dozen ID and payment cards, people will have the option of storing them digitally and presenting them wirelessly. Electronic banking will take off, providing safe, standard web-based APIs around your personal finances and investments.

Our understanding of genetics today will look primitive compared to that of 2020. In 2020, genomics will have high-level structures that understand and codify the development and existence of organisms, allowing us to symbolically describe and modify how genes are turned on and off, like a computer program. We will have genetic fixes for a few of the big genetic disorders today. Some of these fixes will be applied to the human germline as well, wiping the diseases out entirely for descendants.

Car travel will take a number of big steps forward. In 2020, most modern cars will aware of each other to some degree and offer basic driving coordination like avoiding rear-end collisions and traffic management. Most cars will be LTE-capable and have online traffic updates, integration with your personal mail and text-to-speech for handsfree web ‘listening’. Rare features today such as heads-up night-vision displays and 360º visibility cameras will trickle down to a much larger segment of vehicles.

Personal space travel will be uncommon, but available for individuals for a cost around $100,000. Small space travel outfits will have small, but permanent space stations for the travellers to dock and stay for a few nights. Humans will be in the planning stages for the first extra-terran mission in our solar system since the moon landings which will involve nations from around the world.

Thoughts on where I’ve missed the boat, or neglected an important up-and-coming change? Leave comments below or select a paragraph to add your thoughts inline.