SPDY: The Web, Only Faster

Of all the exciting stuff that’s happening at Google, one of the things I’ve been most excited about is SPDY, Mike Belshe and Roberto Peon’s new protocol that upgrades HTTP to deal with many of the new use-cases that have strained browsers and web servers in the last couple of years.

There are some obvious advantages to SPDY; header compression means that things like cookies get gzipped, not just content, and mutliplexing over a single connection with priority information will allow clients and servers to cooperate to accelerate page layout based on what’s important, not only what got requested first.

But the the really interesting stuff from my perspective is the way SPDY enables server push both for anticipated content and for handling Comet-style workloads. The first bit is likely to have the largest impact for the largest set of apps. Instead of trying to do things like embed images in data: URLs — which punishes content by making it uncacheable — SPDY allows the server to anticipate that the client will need some resource and preemptively begin sending it without changing the HTTP-level semantics of the request/response. The result is that even for non-cached requests, many fewer full round trips are required when servers are savvy about what the client will be asking for. Another way to think about it is that it allows the server to help pre-fill an empty cache. Application servers like RoR and Django can know enough about what resources a page is likely to require to begin sending them preemptively in a SPDY-enabled environment. The results in terms of how we optimize apps are nothing short of stunning. Today we work hard to tell browsers as early as possible that they’ll need some chunk of CSS (per Steve’s findings) and try to structure our JavaScript so that it starts up late in the game because the penalty for waiting on JS is so severe (blocked rendering, etc.). At the very edge of the envelope, this often means inlining CSS and accepting the penalty of not being able to cache for things that should likely be reusable across pages. On most sites, the next page looks a lot like the previous one, after all. When implemented well, SPDY will buy us a way out of this conundrum.

And then there are the implications for Comet workloads. First, SPDY multiplexes. One socket, many requests. Statefully. By default. Awwwww yeah. That means that a client that wants to hang on to an HTTP connection (long polling, “hanging GET”, <term of the week here>) isn’t penalized at the server since SPDY servers are expected to be handling stateful, long-lived connections. At an architectural level, SPDY forces the issue. No one will be fielding a SPDY server that doesn’t handle Comet workloads out of the box because it’ll often be harder to do so than not. SPDY finally brings servers into architectural alignment with how many clients want to use them.

Beyond that, SPDY allows clients to set priority information, meaning that real-time information that’s likely to be small in size can take precedence on the wire over a large image request. Similarly, because it multiplexes, SPDY could be used as an encapsulation format for WebSockets, allowing one TCP socket to service multiple WebSockets. The efficiency gains here are pretty obvious: less TCP overhead and lowered potential for unintentional DoS (think portals with tons of widgets all making socket requests). There’s going to need to be some further discussion about how to make new ideas like WebSockets work over SPDY, but the direction is both clear and promising. SPDY should enable a faster web both now and in the future.

A Bit of Closure

So from time to time I’d wondered what all the brilliant DHTML hackers that Google had hired were up to. Obviously, building products. Sure. But I knew these guys. They do infrastructure, not just kludges and one-off’s. You don’t build a product like Gmail and have no significant UI infrastructure to show for it.

Today they flung the doors open on Closure and it’s supporting compiler. These tools evolved together, and it shows. Closure code eschews many of the space-saving shortcuts that Dojo code employs because the compiler is so sophisticated that it can shorten nearly all variables, eliminate dead code, and even do type inference (based on JSDoc comments and static analysis).

There’s a ton of great code in Closure, so go give the docs a look and, if you’re into that kind of thing, read the official blog post for a sense of what makes Closure so awesome.

It’s interesting to me how much it feels like a more advanced version of Dojo in many ways. There’s a familiar package system, the widgets are significantly more mature, and Julie and Ojan’s Editor component rocks. The APIs will feel familiar (if verbose) to Dojo users, the class hierarchies seem natural, and Closure even uses Acme, the Dojo CSS selector engine. It’s impressive work and congrats are in order for Arv, Dan, Emil, Attila, Nick, Julie, Ojan, and everyone else who worked so hard to build such an impressive system and fight to get it Open Source’d.

WebKit, Mobile, and Progress

PPK posted some great new compat tables for various flavors of WebKit-based browsers the other day, editorializing that:

…Acid 3 scores range from a complete fail to 100 out of 100.

This is not consistency; it’s thinly veiled chaos.

But I’m not convinced that the situation is nearly that bad.

The data doesn’t reflect how fast the mobile market changes. The traditional difference between mobile and desktop, after all, has been that mobile is moving at all. If you figure a conservative 24 month average replacement cycle for smartphones, then the entire market for browsers turns over every two years. And that’s the historical view. An increasing percentage of smartphone owners now receive regular software updates that provide new browsers even faster. What matters then is how old the WebKit version in a particular firmware is and how prevalant that firmware is in the real world. As usual, distribution and market share are what matters in determining real-world compatibility, and if that’s a constantly changing secnario, the data should at least reflect how things are changing.

So what if we add a column to represent the vintage of the tested WebKit versions? Here’s a slightly re-formatted version of PPK’s summary data, separated by desktop/mobile and including rough WebKit vintages (corrections and new data much appreciated if you happen to know!):

Desktop
Browser Score (max 216) Vintage
Safari 4.0 204 2009
Chrome 3 192 2009
Chrome 2 188 Early 2009
Safari 3.1 159 2008
Chrome 1 153 2008
Safari 3.0 108 2007
Konqueror 3.5.7 103 2007
Konqueror (newer, untested) 0 ??
Mobile
Browser Score (max 216) Vintage
Ozone (version?) 185 (?) Late 2009
iPhone 3.1 172 2009
Iris (version?) 163 (??) 2008
JIL Emulator (version?) 162 ??
Bolt (version?) 155 ??
iPhone 2.2 152 2008
Android G2 (version? 1.6?) 144 (??) Late 2008
Palm Pre (version?) 134 ??
Android G1 (1.5?) 108 (??) 2008
Series 60 v5 93 (??) 2008
Series 60 v3 (feature pack?) 45 2005

PPKs data is missing some other columns too, namely a rough estimate of the percent of mobile handsets running a particular version, rates of change in that landscape over the past 18 months, and whether or not these browsers are on the whole better than the deployed fleet of desktop browsers. Considering that web devs today still can’t target everything in Acid2, knowing how the mobile world compares to desktops will provide some much-needed context for these valuable tables. Perhaps those are things that we as a community can chip in to help provide.

Even without all of that, just adding the rough vintages adds an arc to the story; one that’s not nearly so glum and dreary. What we can see is that newer versions of WebKit are much more capable and compatible, even at the edges. None of PPK’s data yet tests where the baseline is, so remember that the numbers presented mostly describe new-ish features on the platform. We also see clearly that the constraints of the mobile environment force some compromises vs. desktop browsers of the same lineage. This is all in line with what I’d expect from a world where:

  • WebKit is becoming the dominant smartphone rendering engine, finding its way into myriad devices due to its performance, compatibility with web content, clean C++ codebase, and straightforward API
  • Vendors upgrade the version of WebKit they ship when they release new OS versions. Very few mobile devices enjoy long-term OTA updates (yet).
  • Deployed smartphone stock turns over every 2 years

The important takeaway for web developers in all of this is that WebKit is winning and that that is a good thing. The dynamics of the marketplace have thus far ensured that we don’t get “stuck” the way we did on the desktop. That is real progress.

Where do we go from here? Given that the mobile marketplace is changing at a rate that’s nearly unheard of on the desktop, I think that when new charts and comparisons are made, we’ll need to couch them in terms of “how does this affect the difference in capabilities across the deployed base”, rather than simply looking at instantaneous features. Mobile users are at once more likely tied to their OSes choice of browser and more likely to get a better browser sooner. That combination defies how we think about desktop browsers, so we’ll need to add more context to get a reasonable view of the mobile world.

More Orthodox Heresy

  • Dynamic languages can’t be fast relative to static languages
  • Any language with a working lambda can be saved from itself, given a fast enough runtime. But you can’t save the other folks who use that language
  • You agree with me
  • RDFa is smart technology, and can be cleanly integrated into HTML
  • It was all invented in the 70’s
  • Java-style static typing prevents me from doing dumb things in the small. This makes it awesome.
  • You slow down as you get older, but it’s a learned response. You get there because you find caution useful. You stay there because you find caution comfortable
  • Java-style classes prevent me from doing smart things in the large, or at least makes smart things harder to communicate. This makes it terrible.
  • Dynamic languages can be more than fast enough.
  • Your language is probably better than my language
  • C++ made it all possible years ago, but nobody noticed because their compiler didn’t support it yet
  • RDFa is doomed to inevitable, painful failure
  • Making it common is more important than making it to start with
  • Forging agreement is hard, sometimes impossible
  • You violently disagree with most things I say
  • The more things change, the more they change

9L30 != 9L31a

Somehow I got out of sync with everyone else in the local distcc cluster at work. How? Weirdly, the XCode settings showed that while there were plenty of peers around to build with, they were all slightly off (har) in their OS version number, and therefore returned the dreaded “Incompatible Service”.

Some googling revealed that Apple shipped two 10.5.8’s!. A regular software-update won’t trigger the required update, either. Luckily, re-applying the stand-alone updater got me up to 9l31a, and I can once again abuse my co-worker’s CPUs instead of my own. Phew!

Dojo Developer Day, TOMORROW

I’ve been so busy with with work and such that I totally forgot to mention that tomorrow, Sept 10th there will be a Dojo Developer Day in Mountain View, generously hosted by AOL.

Come for the whole day, drop by for a bit, or just join us for dinner/drinks afterward. In the ramp up to 1.4, there’s some great engineering happening in nearly every area of the toolkit, including some great new visual improvements that I expect to see and hear a lot about tomorrow.

As usual, folks will be on IRC throughout the day should you not be able to join us in person, and in a first, we’ll have a live feed of the event going.

Hope you can join us!

A Contract With America

Dear Republican Senators (and Max Baucus):

Since you do not believe that health insurance should always be available via large-group policy to the vast majority of Americans, and since you seem to believe that the individual insurance market functions well, I believe it is only proper for you to buy insurance in the individual market.

As a taxpayer, I’m sure you’re as galled as I am that we’re continuing to insure America’s Senators through a nearly socialist system, and while you haven’t yet discovered the presence of mind to submit legislation to end this objectionable practice and free all of America’s Senators from the yoke of tyranny, you can personally act to see this deeply un-’merican policy corrected. In short, I urge you to find the courage of your convictions and put your health where our money is.

I recognize that legislating in good faith is no longer “on the table” for you. It has to be hard being the party of “no”, never having anything constructive to offer — never being asked to think independently about anything — but this is something that you can do for your country. A contract with America, if you will. Or if not with America, a contract with an individual insurer in the greater District of Columbia and/or your home state…anyway, you get the idea. It’d be a contract for America at the very least.

On this Labor Day, I urge you to do the right thing. Join your constituents and say, with one voice, “what do you mean you won’t cover Timmy’s ear infection? He was just born! How can that be pre-existing!?!” This is “rugged individualism” at its finest. Just you against the private-sector Man. The way it should be.

True, this won’t be a 1:1 comparison since you’re in the top 3% of all earners. But don’t worry, you’ll soon find that you can’t afford the coverage you’re currently enjoying when you buy in the individual market. Your new, terrible, and terribly expensive insurance will doubtless give you the flavor of what the rest of us experience.

Ingeniously, this plan doesn’t even require that you do anything constructive toward health care reform. You can keep stiffing both your country and your constituents and you won’t have to hold any of those awkward “town hall” meetings to explain yourself. After all, this is the fiscally conservative thing to do; you’ll be saving taxpayers money, and who can argue with that?

Pretty soon, you might even be able to find the courage to do what your instincts — and terrible economics — tell you to do: advocate that our retirees buy in the individual market too! Once you discover how great the individual market is, you shouldn’t have any qualms in making the case that everyone should join it. Just think how many people you’ll be able to lift out of the oppressive regime of socialized insurance. The elderly will surely make their thanks known at the ballot box. As someone who’s most likely “getting up there” yourself, you’ll have added credibility on the issue…and seriously, when was the last time you had credibility? This is political gold.

You can even continue to play the part of hostage to broken, antiquated economics if it suits you (and your major campaign contributors, ‘natch).

It’s the very least you can do for your country, and for your (tiny) efforts you’ll be set on a personal journey of discovery. You’ve never seen the pain and burning anger caused by “pre-existing condition” denials for things that are laughably routine. You’ve never wondered in awe at how large a deductible you were suckered into, and you’ve probably never had a plan with a lifetime cap on benefits; so when you really need them, they won’t be there. In fact, I suspect that you have never considered that the majority of us don’t even have actual health insurance.

By buying in the individual market, you can set an example. This is your chance to be a real pioneer! This could even be your first step towards representing a growing constituency — something you Republicans have been searching for: those who have gone bankrupt under a mountain of medical bills because they had the temerity to get sick before they turned 65. Those folks might not have wealth, they might not even have their health, but they sure-as-hell are voters. Just think, you can get in on the ground floor of that action!

Yes, dear Senator, by simply finding your moral compass (you’ve got it back there somewhere, even if you haven’t used it in a while) and following it for just one step, you can help us right this great nation again and return it to glory. I urge you to do this thing for your country, follow your ideology, and deny yourself the kind of care that you’ve worked so hard to deny the rest of us. It’s the Right thing to do, after all.

Sincerely,

Alex Russell

American? Voting age?

Then please do yourself and your family a favor and read this piece by T.R. Reid on how health care in the rest of the world actually works (hint: better, cheaper, faster).

It distresses me that our health-care debate has been launched from false premises and has deteriorated from there. We cannot ignore the ongoing harm being done, cannot deny that others are doing it better (across the board), and must not succumb to the false equivalencies and misdirections being vacuously peddled. Now is the time to arm yourself against the tragedy of ideology with real, observable facts.

Note To Self: Faster Chromium Builds (Updated)

I spend my days in C++ on 32-bit Windows XP in Visual Studio 2005. The build and link times for Chromium are painful on this setup, in part because there has been flakiness with the multi-process build option for VS, in part because the incremental linker which can dramatically speed up builds can run out of memory on some boxes (so is disabled by default), and because Visual Studio steadfastly refuses to give developers any options about how, when, where, and why to rebuild the IntelliSense database. The last one is probably the most intractable. On 64-bit windows, incremental linking is turned on based on the assumption that you’ll have lots of RAM on that shiny 64-bit box. Similarly, Chromium builds using multi-process flags under VS’08 since it’s known to be less flaky there. It seems I run with the “please hurt me more” configuration.

“Distributed builds!”, I hear you scream.

That’s not a bad path. For Mac builds, the office’s ad-hoc distcc cluster is a godsend (particularly given that my Mac is a lowly laptop). For Visual Studio, there’s IncrediBuild, but it has left me wanting a better option. Recently I’ve just thrown caution to the wind and started over-riding the safety valves on /MP and incremental linking via my ~/.gyp/include.gypi file:

{
  'variables': {
    'msvs_multi_core_compile': 1,
    'msvs_large_module_debug_link_mode': '2'
  }
}

You can get these settings to take effect without updating your repo by running gclient runhooks --force from the top level directory if your Chromium checkout. VS should then prompt you to reload the project (assuming you’re using the GUI).

Hopefully this recipe will help others. It has dropped small rebuilds on my system from north of 10 minutes to below 2.

Update: So the real answer, apparently, is to get dual quad-core i7’s running Vista 64 under VS 2008. Holy cow, what a world of difference. All hail the Powers That Be for new, awesome hardware!

CSS 3: Progress! (Updated)

I’ve been in a pretty heated email conversation over the past couple of days regarding how effective (or not) the CSS Working Group has been. I’ve been pretty brutal in my critique in the past (and much of it still stands), but there’s reason to hope.

The best bits are — not surprisingly — being driven by the implementers. Apple is in the driver’s seat, with major contributions for Animations (including keyframes!), 2D Transforms, 3D Tranforms, and Transitions. Great stuff.

Similarly, David Baron (of Mozilla fame) is editing a long-overdue but totally awesome Flexible Box spec, aka: “hbox and vbox”. Both Gecko and WebKit-derived browsers (read: everything that’s not IE) supports hbox and vbox today, but using it can be a bit tedious. Should you be working on an app that can ignore IE (say, for a mobile phone), this should help make box layouts a bit easier to get started with:

/* hbox and vbox classes */
 
.hbox {
	display: -webkit-box;
	-webkit-box-orient: horizontal;
	-webkit-box-align: stretch;
 
	display: -moz-box;
	-moz-box-orient: horizontal;
	-moz-box-align: stretch;
 
	display: box;
	box-orient: horizontal;
	box-align: stretch;
}
 
.hbox > * {
	-webkit-box-flex: 0;
	-moz-box-flex: 0;
	box-flex: 0;
	display: block;
}
 
.vbox {
	display: -webkit-box;
	-webkit-box-orient: vertical;
	-webkit-box-align: stretch;
 
	display: -moz-box;
	-moz-box-orient: vertical;
	-moz-box-align: stretch;
 
	display: box;
	box-orient: vertical;
	box-align: stretch;
}
 
.vbox > * {
	-webkit-box-flex: 0;
	-moz-box-flex: 0;
	box-flex: 0;
	display: block;
}
 
.spacer {
	-webkit-box-flex: 1;
	-moz-box-flex: 1;
	box-flex: 1;
}
 
.reverse {
	-webkit-box-direction: reverse;
	-moz-box-direction: reverse;
	box-direction: reverse;
}
 
.boxFlex0 {
	-webkit-box-flex: 0;
	-moz-box-flex: 0;
	box-flex: 0;
}
 
.boxFlex1, .boxFlex {
	-webkit-box-flex: 1;
	-moz-box-flex: 1;
	box-flex: 1;
}
 
.boxFlex2 {
	-webkit-box-flex: 2;
	-moz-box-flex: 2;
	box-flex: 2;
}
 
.boxGroup1 {
	-webkit-box-flex-group: 1;
	-moz-box-flex-group: 1;
	box-flex-group: 1;
}
 
.boxGroup2 {
	-webkit-box-flex-group: 2;
	-moz-box-flex-group: 2;
	box-flex-group: 2;
}
 
.start {
	-webkit-box-pack: start;
	-moz-box-pack: start;
	box-pack: start;
}
 
.end {
	-webkit-box-pack: end;
	-moz-box-pack: end;
	box-pack: end;
}
 
.center {
	-webkit-box-pack: center;
	-moz-box-pack: center;
	box-pack: center;
}

I’ve been using these rules for some time to good effect. You can use them to easily visually center things (for example):

1
2
3
4
5
6
<div class="hbox center">
    <div class="vbox center">
        <div>...</div>
        <div>...</div>
    </div>
</div>

Or you can use grouping to get nicer form layouts:

1
2
3
4
5
6
7
8
9
10
11
<form action="handler.cgi" method="POST" class="hbox">
	<div class="vbox">
		<label>First Name (required):</label>
		<label>Last Name:</label>
	</div>
	<div class="vbox">
		<input type="text" name="first"/>
		<input type="text" name="last"/>
		<input type="submit"/>
	</div>
</form>

It’s unfortunate that this stuff is “medium priority”, but at least it’s moving forward in the WG.

Update: Fixed the examples and rules to use box-pack: center;, per Dave Hyatt’s excellent suggestion!

Some Orthodox Heresies

Just back from a long weekend, a couple of things struck me this morning that are evident but not perhaps obvious. Reality always has multiple sides, so in true Jenny Holzer style, please accept (but not entirely) these small web-development truisms:

  • Plugins are not evil.
  • The web is a force for social change.
  • The internet centralizes power…slowly…oh so slowly…
  • CSS is the problem. Also, the solution.
  • Competition does not mean that your favorite player wins.
  • JavaScript cannot save you. Even if it could, you should not let it, for the price of this short-term salvation is the end of what you like about the web.
  • Fast is better than slow. Slow is better than closed.
  • A web that isn’t extensible will wither and die.
  • Proprietary can be incredibly fast.
  • The sooner we take HTML out of the hands of C++ hackers, the sooner we’ll screw it up.
  • Extensibility is a crutch.
  • Plugins bring the advantages of slow development, unportable code, hard failure, and security holes to a platform designed to remove them. In other words, they’re totally evil. Also, they make the web awesome.
  • Getting what you want will not make you happy. It is your inner dissonance that brought you to the web in the first place. You might as well own it.
  • “Proprietary” is the loser’s word for “I’m too lazy to copy the good parts”.
  • Small firms are always more nimble and therefore better.
  • You can’t beat big companies in the end.
  • HTML 5 is a cruel joke — I can’t wait for it to be done.

JS 1.8 Function Expressions: The Opposite of “Good”

JavaScript is crying out for a way to write functions more tersely. I’ve added my suggestion to the debate, and was vaguely aware that Mozilla had implemented “function expressions”. It wasn’t until I saw their use in the (excellent) ProtoVis examples that I realized how stomach-churningly bad the syntax for them is. Instead of dropping the word function from the declaration of lambdas, they kill the { } charachters, leaving the big visual turd at the front of the lambda while simultaneously omitting the symmetrical visual aid that allows programmers to more easily spot missing terminators.

Oof.

It’d be one thing of the feature saved enough effort (typing) to justify the confusion, but it doesn’t. Bitter syntactic sugar in a language that’s already complicated by whitespace issues should be avoided.

Perspective

So after receiving a keyboard-lashing from myself and others regarding some comments he made, Chris has walked a lot of it back and bravely noted where his new perspective conflicts with the old. It takes guts to do that.

My original comments were born of my frustration the internecine strife that seems to follow every discussion about OSS licensing. It’s one of the reasons that I was so grateful for Dion’s 100-point scale for judging community because it helps put all of this stuff into a perspective that lets you evaluate what’s more likely to be good for a broad audience from what’s more likely to hurt people along the way. There will always be both individual and corporate involvement in OSS, and both are good things, but neither are unalloyed forces for lightness and right. They’ve got down-sides. OSS communities and hackers should be honest about them and evaluate them on the merits and likely outcomes. It took me a long time to come to that perspective and it’s and one that I’m happy to see Chris weighing. Kudos to him for taking it in stride.

Correction: I wrongly attributed the 100-point scale to Ben instead of Dion. Totally n00b mistake. My apologies.

Automated Dojo Layer Builds in ZF 1.9.0 Preview

Early on in discussions with the excellent folks at Zend, one of the possibilities that made everyone in the room excited was the ability to use server-side smarts about client-side work to automate performance optimizations in ZF apps. After lots of great work on getting Dojo integrated, Zend Framework is making that a reality by support automated custom builds in ZF 1.9.0’s preview release.

What does this buy you? You get to use the Zend helpers for Dojo as you normally would, simplifying how you pull in code, declare components, and build your UI. What this new integration saves you is the tedium of figuring out which components you’re using everywhere, building a layer file for it, kicking off a build, and remembering to re-visit the layer definition when you project adds or removes modules. Hopefully ZF 1.9 should lower the barrier to taking advantage of the full range of Dojo-based optimizations, making it easier to prototype quickly and deploy easily. Exciting stuff!

OSCON dojo.beer() Tonight!

Sorry for the late notice, but the inimitable Matthew Russell has organized another dojo.beer() event for 7pm tonight (Wed, July 22nd) at O’Flaherty’s pub in San Jose, near the convention center. Should be a great time, so if you’re in the area, hopefully we’ll see you there!