Configure player

Close

WWDC Index does not host video files

If you have access to video files, you can configure a URL pattern to be used in a video player.

URL pattern

preview

Use any of these variables in your URL pattern, the pattern is stored in your browsers' local storage.

$id
ID of session: wwdc2007-615
$eventId
ID of event: wwdc2007
$eventContentId
ID of session without event part: 615
$eventShortId
Shortened ID of event: wwdc07
$year
Year of session: 2007
$extension
Extension of original filename: mov
$filenameAlmostEvery
Filename from "(Almost) Every..." gist: ...

WWDC07 • Session 615

Using Dojo Toolkit Power Tools to Build Rich Web Applications

Content and Media • 1:06:39

Learn how Dojo enhances web applications and helps you build compelling interfaces using Open Web technology. Join members of the core Dojo team as they show you how Dojo's unique features let you upgrade your applications incrementally and even while off-line; we will work our way from basic AJAX through the latest technologies in WebKit.

Speakers: Dylan Schiemann, Alex Russell

Unlisted on Apple Developer site

Transcript

This transcript has potential transcription errors. We are working on an improved version.

George: We're covering Dojo Toolkit Power Tools presented by none other than the actual founders of the Dojo Foundation and the owners of SitePen. So at this time I'd like to welcome up on stage Dylan Schiemann and Alex Russell of SitePen. Um, come on up guys. Thank you very much.

(Applause)

[Dylan Schiemann]

Thanks for coming. I'm Dylan. This is Alex. Thank you, George. Let's see how this works. So, when we started working on this project called Dojo, about three years ago or three and a half years ago, we were at a point where basically the open web was under attack.

Flash was becoming ubiquitous, DHTML was dead. No one really cared about JavaScript, and we said, well what can we do now? What's, you know, what's possible? And fast forward three years and now the world is, wow, AJAX everywhere all the time non stop. So what's next? What's happening? Is the browser done? You know, can we make due with what we have today? What do we need to do next, et cetera? HTML itself, it's terrible. It's lousy for building applications. It's a page and document layout language. What can we do about that? And that's where Dojo comes into play.

We do things to make your job as UI developers much much easier. We create things that basically get rid of the inconsistencies and problems and quirks with today's browsers as well as trying to provide solid engineering principles to things like event models and AJAX requests and DOM manipulations.

At the same time, one thing Dojo's always been pretty big at is pushing the web forward. So we've been investing significant resources and time in vector graphics support across browsers which now works in Safari 3, Opera, Firefox, and Internet Explorer. We've also been working on Offline. And I'm sure most of you have heard about Google Gears and Dojo Offline. And Dojo Offline works now with Google Gears. We're also just trying to make life easier for you. That's really the bottom line what Dojo's about.

[Alex Russell]

Hi, I'm Alex. So today we're going to cover a bunch of the tools that we're trying to fix or perfect in Dojo to make it so that when you go to build an application, HTML takes you as far as it can go. HTML and CSS is a beautiful way to declaratively out your page and we're going to show you today the tools that we're providing so that you can take your HTML and CSS that one step further. We don't try to make HTML and CSS something that it's not.

We don't try to do something that's not webbish, but we do try to provide incremental upgrades. And we're going to show you how we incrementally upgrade pages. We're going to show you web features like Comet and I don't think we're going to talk about vector graphics today, but we are definitely going to show you some of the API's that we're working on for Offline. And we're going to show you why using Dojo on Safari 3 slash WebKit is probably the best experience you can deliver to your users today.

So to do that, to get through those points, we're going to cover some of the core Dojo API's that we're going to use to get there. We're going to talk about how you can wire up the mark up you've already got to declaratively provided behaviors, talk about how you can take the mark up you've got and improve it into entirely new muted, essentially, into entirely new UI's and then look at the things that we talked about like GFX and storage.

So with Dojo we have, for a very long time, taken the approach that mark up is the right way to set up a UI. There are many piles of JavaScript out there that you can choose from today. There's YUI and Prototype and there's going to be a great talk tomorrow by Sam Stephenson, the author of Prototype and Prototype, and Dojo is one of these piles.

And Dojo has, for a long time, taken the approach that we want to continue to be able to take the advantages of mark up, being able to declare stuff where we get it, where we want to show it in the page, being able to degrade gracefully, being able to provide semantic information in our mark up about what it is we want to see on the screen and provide that across as many devices as we can so that we're providing tools that will allow you to do this in the page itself.

One of the things that we've learned in the, I think four and a half years since we've been employing a JavaScript mark up for mutating the DOM is that JavaScript is a pretty good way for programming and XML and mark up languages aren't. Has anyone used Ant? Yeah? Who hates it? Okay. Yeah. That's about half of you. All right.

[Dylan Schiemann]

Sorry Eric.

(Laughter)

[Alex Russell]

So one of the major pain points of a tool like that is that XML turns out to be a really tweaky way to declare things that can be very densely spoken about in a programming language, as opposed to a mark up language. So what we're trying to do in Dojo 0.9, and we'll show you how we're going to do it, is unify some of those differences so that your mark up and your script no longer feel like they're in opposition. They can talk to each other; they can be scoped more easily and we'll show you how we're going to get there more easily with that.

[Dylan Schiemann]

The other thing we've really tried to think about is people like HTML and CSS; they know HTML and CSS, so in many cases, how can we make live easier for people that know HTML and CSS?

[Alex Russell]

Great. So we're going to dive right in with some code examples. There's going to be a lot of code examples today, so if you don't like code, maybe you should find another talk. So this is a pretty simple straight forward HTML page. What we've got here is a non conformant document of NEDTD.

And if you zoom in to the next highlight, you'll see that we're pulling in Dojo, the library, and that's going to pull in a bunch of stuff that we know that we're going to need, and including a package system. So if you go ahead, we're going to show you that we're pulling in a date and text box which is just something that augments our regular old HTML input element, but we know that we're going to input a date.

So the (inaudible) and the WD3C are collaborating in HTML 5 which are going to give us richer semantics for a lot of the kinds of things we're able to do now only with JavaScript. But until we get there we need something better. So what we're going to do is if we keep going down the page we can see that we've got a regular input node and in that input node we've added some extra attributes.

So particularly Dojo type, which says we're going to create an instance of the class here and we're going to use this node as its constructure. And then another property which only applies to the date text box class, but we're going to set it as a value on that instance of this thing. So can we jump to the first demo?

[Dylan Schiemann]

Yes.

[Alex Russell]

Thanks. So this is what we get out of all that. If you yeah. Open that up. You can see that we've got a better UI for declaring this stuff. Can you enter an invalid date? I'm afraid that's still valid. Yeah. (Laughter)

[Alex Russell]

Oh yeah. There we go. So we get some UI help and if you do go into the preferences and turn off JavaScript you can see that we get the same advantages that we've always gotten with the web which is the thing is to degrade gracefully. So if a user agent can't handle sending it, we still get the best UI possible. We're not changing the way you build an application, we're only giving you upgrades to the web that we ship today. We can't wait for the browsers to do this natively. We just can't wait. So we're doing it ourselves.

[Dylan Schiemann]

Our goal is in five years for all of our code to be obsolete that we have today, and be replaced by new and more interesting stuff.

[Alex Russell]

Can we go back to slides?

[Dylan Schiemann]

Yes.

[Alex Russell]

Thank you. All right. So that's pretty good. That gives us the ability to upgrade a bunch of the input elements that we've always wanted some nicer UI looking feel and augmentation for. Better affordances for some of those things. But HTML falls down primarily when it comes to laying out pages. Now I have participated in any number of mailing list threads about how you can bend your head in the right way to make it look like across browsers. You can lay something out in three or four columns in CSS.

I'm sure many of you have done the same thing. But what we would like to be able to do is specify things that we can't do in CSS today or that the browser implementations don't get us all the way to. So if you look at the various browsers today, we have things that are dash moz, dash KHTML, dash Opera, dash WebKit prefixed, and those provide us with the power of the stuff that the CSS working group is still lethargically specifying that we would love to get to someday.

But until then we still need to build more complex layouts. So Dojo provides a whole set of panel based layouts which provide you constraints, which provide you relationships, and give you the ability to mark up those things using the HTML and CSS you might already have laying around.

So again, this is a pretty simple example of the market that we might have used in order to layout a couple of things side by side. Now when we lay something out in a table, obviously we're using a table which in HTML is supposed to specify some tabular data.

We don't have tabular data here most likely; we just have some stuff that we want to have side by side gosh darn it. So and we'd love to be able to put the user in control of how those things are rendered out over time. Unfortunately a table doesn't give us that.

The user can still specify font sizes, they can go ahead and they can tweak all other kinds of things, but they can't change the relationships between those. And we can't specify necessarily anything more than a single percentage and fill relationship or a set of percentage and fill relationships.

We'd love to be able to say, this one is this, this one is this percentage. The other is this other one minus five. I mean CSS should be an expression language, but it's not. So we can get a lot of that stuff if we use something different. Can you go to the next slide?

[Dylan Schiemann]

CSS can't do math basically.

[Alex Russell]

Yeah. We'd love to be able to do math because you'd love to be able to do math. So instead, what we're doing is we're pulling in Dojo again and we're using the package system to pull in the split container widget which lets us take some stuff specified in a splitable container and put the user in control of that layout and then a content pane. And the content pane is just an abstract container for some stuff that we're going to manage the layout of. Fair enough.

So now if you look at our mark up here, instead of having a table which specifies some non semantic mark up, what we've got is more or less semantic mark up, or at least inert mark up from the semantic perspective which is being augmented with the properties that we care about to construct a layout that puts the user in control without necessarily jeopardizing our ability to render it correctly across devices should the device we're on not handle the JavaScript we're showing. All right.

But we can do more than that. We can also take much the same mark up and because Dojo has a pretty well laid out class system, we can do the same thing with tabs. So the same mark up that it takes to crease a split container can represent stuff that's stacked.

I mean this is just layout primitives which we're stacking or putting side by side. So the container and panel stuff in Dojo is pretty powerful. And you'll see that the only additions that we have to make here, instead of specifying a split container for our content, we're specifying a tab container and then we're adding a title. Excuse me.

I apologize. I should have updated these slides. We changed that from label to title this week. We should have a title attribute which will specify what the title of the thing is going to be. It's a little bit of extra meta data. It's semantic. We want to be able to display it in a UI that cares about it, but not in one that doesn't.

And how do they look? Well, I think they look pretty good now. And the great thing about these, these are Dojo 0.9 widgets by the way. This is not what you're going to get if you go download the main Dojo release day. This is what we're going to be shipping a beta of next week. So

[Dylan Schiemann]

And you're not going to get the default drop Apple drop shadow either. That's just a nice slide effect.

(Laughter)

[Alex Russell]

I apologize for that. So we've got these tabs and your CSS is what makes them look this way. If you specify a CSS on those content panes or on the split container or on the tab container, that CSS is going to get copied over and translated into whatever the resulting mark up is. So if you know HTML and CSS you can use the HTML and CSS mark up you know to augment the behaviors that you're already implementing.

[Dylan Schiemann]

How many of you have used Dojo 0.4 by the way, just so we know?

[Alex Russell]

All right.

[Dylan Schiemann]

A small percentage.

[Alex Russell]

So going down one level, a lot of folks don't necessarily want these kind of precanned widgets. If you're a professional web developer, you know what you know and you know that you don't want us to know more than you know because we probably don't.

(Laughter)

[Alex Russell]

So you've got a lot of existing mark up and you'd love to be able to just augment it with some behaviors. So not everything needs a widget. And we want to make sure that the mark up that we've got can get better over time.

[Dylan Schiemann]

Sorry.

[Alex Russell]

And there are a bunch of libraries out there today which can make it so that the mark up you've got can do stuff that it couldn't when you initially laid out laid it out on the page. This is all about progressive enhancement as it's become known recently.

But the behavior libraries that you can get today tend to be pretty slow. So there's kind of an arms race on among the JavaScript library authors which benefits all of you because this arms race is all about who can implement the best selector syntax across the DOM as it sits in your browser today and make it the fastest.

And so we've got a pretty fast implementation of that and we'll talk about that in just a second. But a lot of them to date have been pretty slow. If you call apply a couple of times on 'em, you'll get the same behavior applied to the same nodes multiple times, and that's not what you want more or less. In many cases you want to take a CSS selector, specify a behavior, and then specify another behavior and not have the first behavior reapplied to it. So Dojo dot behavior, which is the system we'll talk about here, doesn't do that.

Dojo dot behavior is reapplication safe so that if you specify multiple rules additively at multiple points in your code, you'll know that when you call apply, Dojo dot behavior dot apply, you're only going to get the new rules on the new nodes; and if you've got old nodes which were previously matched, you'll only get the difference in rules applied to the old nodes. So the system mark up, you know, we've seen mark up like this before, and we're going to take it and we're going to augment it with some Dojo dot behavior.

Some day. So we're going to pull in Dojo dot behavior as we've seen before, and I apologize that this is a little bit dense. But all we're doing is we're setting up one function called toggle content. And toggle content is just going to say in reference to the node that generated this event, find the related node and slide it in.

Okay. And then at the bottom is the juicy part. Dojo dot behavior dot add takes an object whose keys are any valid CSS 3 selector. So if you've got a CSS 3 selector, whether or not your browser implements CSS 3, you can use it to query properties. And this supports things like N plus one odd and even, sibling and child relationships, all that kind of good stuff. Compound rules, the kind of stuff that you'd expect out of a good engine.

And there's a special property that's being set at this element and that property can be a list of event handlers to set. So if you specify on click, on mouse over, whatever, the function that you specify next, or the topic name that you specify next, will get used as the handler for that event. But in this case we're going to use a specially named one called found, and that's going to whenever this rule matches a node, that node is going to get passed into the found function.

So we're just going to set up some behavior here when we find a node. And then when we click it you can see we're going to call toggle content. So this is a nice way to take to mark up what we've got, mix in some JavaScript, and get a better UI out of it necessarily.

Okay. We're going to show you an example of that in a bit, but not right now. But so to understand why Dojo dot behavior does what it does or how we get there we looked at the entire set of selector syntaxes that were available. And when we looked out there we saw that there was XPath, there's OGNL, there's CSS 1, CSS 2, and CSS 3.

And browsers don't give us a fast path for getting to almost any of them today. And when I say browsers, I mean every browser because what we do in Dojo has to work in every browser. So luckily we've got XPath implementations across the HTML DOM in WebKit and in Firefox. And I believe soon in Opera, if not today. IE is obviously the odd man out. And we don't have CSS selectors yet really on any browser.

So one choice, the kind of path of least resistance would be to implement XPath inside of IE in order to give you the native selector syntax. But web authors really aren't XML people and we're not XML people. We don't like XML. I know that's probably heresy, but XML is kind of a bug. And (Laughter)

[Alex Russell]

It should be the browser's job to figure it out, right? So what we said is, okay, web authors know how to do CSS, we know how to do CSS. And CSS 3 is kind of powerful. So what we're doing is we're taking CSS and on the browsers that do handle XPath, we're translating two XPath selectors where it's fastest, because it isn't always fastest, especially in WebKit. WebKit's DOM is so fast that we can use a DOM iteration and it's faster than it's built in XPath.

And both blew everything else out of the water. We'll show you that in a bit. So we've tuned this thing to the hilt. And again, this is an arms race. A lot of the other tool kit authorize are doing the exact same things right now, but we think we've got a pretty good entry here. And Dojo dot query is baked into the core of Dojo 0.9. Whenever you call on that Dojo dot JS, you always get Dojo dot query.

So to give you an idea of some of the stuff you can do in Dojo dot query, we've put together a couple of little examples here. So the first one shows you querying every element in a document for something with a property set. It doesn't have a particular value, but it has that property set. And we're going to get back in array. We're going to get back in a real honest to goodness array. We're not going to get back some kind of weird class that we made up. We're going to get an array.

So you can say Dojo dot query. And as you get it back you can say bracket zero whatever and get the first element or bracket N whatever. Or you can do foreign iteration on it just like you would anything else. But we're also augmenting it with some other nice methods like connect and style and styles which let you take operations across all of the elements of that return value.

So in the second example here we're going to find all the buttons and connect a particular function to them. So if you don't want to use Dojo dot behavior, you can still get much the same result by specifying a connect handler on any element or group of elements.

[Dylan Schiemann]

Why would you want to use query and not behavior?

[Alex Russell]

Query is baked in to Dojo 0.9's base Dojo dot JS. Behavior's available through the package system, but you get Dojo dot query all the time. And I think I think the second to last one is the most baroque example. We're going to scope our query by a particular I.D. and then we're going to get every odd table row and then we're going to get all the table element children of those odd table rows and animate them. So this is how we can take some simple CSS selectors that we know how to use and augment the mark up we've already got on the page with some nice power.

All right? So we showed you the widget system, or just the beginning of the widget system. We showed you how you can take some mark up, augment it with some extra elements, and get something else in the page in return. But we can create classes of any type for our mark up. So Dojo 0.9 has a parser. We're calling it Dojo dot parser.

And it looks for those things that have the Dojo type property set. When we get the Dojo type property, we look at the value that's in there and we create an instance of that class. It doesn't have to be a widget. In Dojo 0.4 we always looked for that and then tried to match it up with the widget class.

So if you had something that wasn't a widget, you actually probably had to wrap it in a widget class in order to get an instance of it through the mark up system in Dojo 0.4. In Dojo 0.9, we're removing that barrier so you can create instances of any type. So that means that you can take, as we'll see in just a second, data binding or setting up classes that you might have laying around that effect other stuff in your page and

[Dylan Schiemann]

Or just defining stuff you would normally define in script.

[Alex Russell]

Yeah.

[Dylan Schiemann]

To substantiate it.

[Alex Russell]

Yeah.

[Dylan Schiemann]

Just don't have to pull up a script block and remember scripts syntax. You can just use simple mark up to

[Alex Russell]

And you can set properties on them. Any property that's on the prototype of that class can be handled as an attribute of the node that you're declaring an instance from. Well let's go look at how you use that because it seems a little bit abstract, right?

[Dylan Schiemann]

Yeah.

[Alex Russell]

So here's one case where Dojo 0.9 has a Dojo dot data name space and that defines a bunch of stuff that conforms to a particular data access API. It's nice and flexible. You can get CSV files, you can go out to external services, you can go and you can grab JSAN. And in this case we're going to grab a little bit of JSAN. And we can see that the argument to that JSAN item store constructure is an object with a URL property. So, oh, can you go back?

[Dylan Schiemann]

Sorry.

[Alex Russell]

Our tree would really love to be able to use that source so it's going to look at and find a JavaScript object named CS, which we're defining above, and using it to expand out the nodes of that tree based on our data store. Pretty good. Okay. So we can back all of our trees with data stores. But a tool might not want to do that. A tool might want to generate some mark up.

So tool could generate the exact same functional thing using the Dojo type syntax to create new instances of that class and pass in pass in the URL parameter and assign that instance of that class to the name CS in the JavaScript names base. That special attribute, JSID can be anything. It can be foo dot bar dot bass and we're going to assign this instance to foo dot bar dot bass. Pretty good. So we can move a lot of the stuff we were doing in script before into mark up if it makes sense.

Let's go. Again, that's a little bit abstract. We might need it in some cases. We might not need it all of the time, but one of the things it also allows us to do is define instances of new classes. So we put together a 50 line widget called dijit dot declaration. Dijit dot declaration lets us define a new widget.

So this is a new widget. So Dojo widgets have had a dollar curly whatever variable curly replacement syntax for taking properties on in instance and pushing them into a templated output. And we can use the exact same thing here in our mark up and then declare instances of it. So if you jump through this a little bit you can see that we're going to create an instance of dijit dot declaration. It's got a special widget class property which is the name of the class that we're creating.

We're going to specify some properties that we can set and then we're going to mirror those properties out inside of the rest of the children of this element. So that's going to get used as the template when we create instances of it. And then we can use instances of it immediately thereafter. So you can create a widget without ever touching JavaScript today in Dojo 0.9. It's pretty powerful stuff. Let's look at how we'd use this.

[Dylan Schiemann]

Yes.

[Alex Russell]

So we talked about that splitter example. Can you show us the code Dylan? Oh yeah. You can drag 'em. Users are in control. The CSS works. That's our example. As you can see, we've got some CSS apply, which wasn't in the slide, to specify stuff. There's a sizer width, so if we want to make the drag handle different we can specify a vertical split, we can specify a horizontal split; we can lay the stuff pretty much out however we want. And the CSS that gets applied to those content panes is mirrored out inside of our resulting layout.

So let's look at how that would how much the same thing would look as a set of tabs. So we can switch between those tabs just like we would expect we should be able to. And if you look at the source it's just as simple. Our mark up is more or less semantic.

We don't have constructs for doing this stuff in HTML today, but we can fake it. And this is really important from an accessibility perspective. All the widgets in Dojo 0.9 will be accessible on the browsers that can support it today. And that means that if you've got a screen reader, if you've got system technology, if you've got high contrast mode, the Dojo 0.9 widgets are designed to work with those assistive technologies out of the box. And so on devices which don't even have that level of functionality we can provide really good mark up as a result, even if they don't have any other assistance.

So we show you that behavior system. And the behavior system so this is an example of us using behaviors to go clone those nodes and, yeah, and you can see that we're applying a behavior to a group of nodes, each one of them to each other. Can you go and turn off JavaScript and reload that page? Thanks. So we can see here that what we get as a result is that button doesn't have a behavior applied. It's just the market that was there.

And the initial content wasn't rolled up so that if we don't have JavaScript in the page, if our browser can't handle it, if our device isn't that good, we still get the content that we would expect from the mark up itself. Everything is semantic and the behavior is split out from the mark up. We weren't the first to do this, but we think we have a pretty good implementation. All right. Oh. Yeah, let's not look at that.

[Dylan Schiemann]

All right. (Laughter) >> Alex: Oh, it's an eye chart. So we talked a bit about no. Can you zoom out? Ah yes. There you are.

[Dylan Schiemann]

Okay.

[Alex Russell]

We talked a little bit about being able to declare instances of any type and back stuff with data stores declaratively. If we look at the service for this page, what we're going to see is that we've got that country JSAN thing and we're just, we're going to use a little class that we called WWDC dot repeater. And all it does is take that data store that we're going to pass into it and it's going to take an instance of whatever class we specify and repeat that thing with parameters passed from the JSAN that we're backing it with.

So in order to get a continent repeater, a set of buttons that do this, we're going to use this thing as a little hub. We're going to create some buttons, repeat 'em, and then wire them up as repetitions to the continent store with that query. That's all the easier it is. And the code to do this is really straight forward. So, but that's not necessarily useful. Let's go back and look at the next example, zero six.

So this is a repeater that can filter. So our data store can accept any set of queries that it'll implement and you can see that we can filter the stuff in our page just by using the data store and a repeater to create instances of any type. And most of these widgets are being declared on the page or are a stock Dojo widget.

So can you look at the source for that? One of the things you will note here is in the on item method we've got a little bit of oh, is this the right one? Ah. Yeah. This is the next one. We've got a little bit of code here with Dojo X dot wire.

And Dojo X dot wire is going to take a property, map it to from one particular class into a property of another class and we're going to pass that in. And so if you scroll down you can see that our repeater here now has a property called mappings. And that set of mappings is what we're going to display on our button. We're going to say, on the button class, specify the name attributes from the caption element of the data items that we're representing here.

So we can wire up any property on our Dojo dot data items to any property that resulting classes, or set of properties in the resulting classes, and repeat them as we like and filter them in realtime. And it's all in a couple of pages of code. We think this is pretty powerful.

[Dylan Schiemann]

Yeah.

[Alex Russell]

But just getting the data from that itself is okay. But what we'd like to be able to do is interface this with external services. So what we've got here is a is a same repeater, but we're creating instances of an article class. And the article class is going to go out, and we looked at Yahoo News for whatever the latest news is on any of these continents. So we put together a little bit of a news aggregator here where we can zoom into anything and filter our news by whatever it is we'd like to look at.

And if we look at the source code again, it's all mark up driven. So we've got that same wiring code if we scroll down into the on item, that hasn't changed at all. And what we do here is every time we and run query here every time we create an instance of our repeater, we're going to run a query on it. And then when we filter with that input box we just pass in a new query.

And then in our get news method, we're just going to use some built in stuff in Dojo to go out and call to Yahoo's public web services. We didn't have to do anything special. There's no proxy, there's no server site code here. This is all what you can do with Dojo out of the box today.

And we didn't specify any of these widgets outside of what's already in Dojo or what we declared in the page itself. So we've gone from some simple mark up representing some stuff that we thought we'd want to see on the page to something that HTML just can't do today. Do you want to Dylan, do you want to show us some of the other power tools that we just

[Dylan Schiemann]

Sure. Sure.

[Alex Russell]

come in to?

[Dylan Schiemann]

Yes. So this is a brand new application called Turbo Studio and what it does is it lets you assemble Dojo based applications, or applications that are pretty much any JavaScript, within the browser and it's built using Dojo 0.9. So you can very easily go through, add calendars, you can allow it to fit the space, you can use all the sorts of container widgets we've been describing. The nice thing is it outputs the exact same Dojo code you would write by hand. Let's see if I can

[Alex Russell]

What about attaching events?

[Dylan Schiemann]

What about them? (Laughter) >> Dylan: I'm just kidding. You can go in and you can basically do your same sort of, well not in that widget, but you can go in and you can bind to any of the events handlers defined by that widget and define exactly what's going to happen to connect an event. And then you can go through and you can edit the code and you can, you know, make it actually do something all within this nice visual browser based tool.

[Alex Russell]

And what about custom widgets? How do we marry custom widgets with this thing?

[Dylan Schiemann]

Custom widgets simply require a custom name space and you can insert them. All right. We created the world's lamest widget ever, which is just a box. It has a close handler. Its properties, you can edit style in realtime, or not.

[Alex Russell]

What about the what about the widget class? Do I have to do anything to the widget class?

[Dylan Schiemann]

If I can find the code. Ah right. It's in tech center. Very good. So the the code we wrote for this is just very straight forward. You can go through and you see a declaration called create the widget. You define its name space. You define what it inherits from.

You define a template, which is just this cool box in HTML. It's just a very simple HTML file, and then some basic things. Caption box so we could go in here and we could change the caption to foo. We could come down here and we could add an event handler.

[Alex Russell]

Semi.

[Dylan Schiemann]

Did I miss that? It's a semi and not a colon?

[Alex Russell]

No. Comma.

[Dylan Schiemann]

Duh. Thanks. There. All right. I'm going to dump cache just because that's always a good idea. I didn't save the project so I'm going to create a new cool box. And you see it has the new handler and it also now has an event handler defined as well.

[Alex Russell]

So this is a quick way for us to take the widgets that we're developing, either declaratively in the page or in JavaScript using the Dojo widget class hierarchy to easily wire stuff up, augment the mark up we've got, and go from there.

[Dylan Schiemann]

Okay.

[Alex Russell]

Can we go back to the slides?

[Dylan Schiemann]

Back to the slides please.

[Alex Russell]

Thanks.

[Dylan Schiemann]

So what happens when you lose your internet connection? The plug gets pulled, your wi fi goes down, and you're working on a blog post. You're using an application and suddenly or you're on an airplane and suddenly you can't use your application anymore? There are a lot of existing solutions. There are, of course, desktop applications. There's Adobe's Apollo or now Air.

There's application specific code, Zimbra offers a solution. And then there's browser augmentation. There's the new Google Gears plug in which Dojo Offline works with, and there's the Firefox 3 effort to off line API's to the browser. So what does off line mean, right? What are the concepts that we need to define? Well there's several cases.

There's what some applications are very clearly defined what would happen; what it means to go off line. For example, editing a blog. It pretty much means I want to be able to edit posts, type them up, and then when I am connected to the internet publish them or sync them to my online service.

Other services it's not quite as clear. What about Google Maps? Well I don't know what it means to use Google Maps off line because you can't search for new data. But maybe you could store your most recent 20 queries to Google Maps or some similar concept. And so the goal of Dojo Offline initially was to solve this off line problem.

And with Google coming along we decided to partner with them. And basically we're providing high level API's to extract away the difference between Google Gears, Firefox's native support. You know, when WebKit or Safari comes out with off line, API will support that as well natively, and just provide nice friendly JavaScript API's for working with off line.

So we handle synchronization and the way we do that is we basically do a log replay mechanism. So everything that happens on the client's side is logged and then if those events don't get published to the server, don't get to the server when you get reconnected we attempt to replay them one by one until the server is in sync with the client.

We also tried to solve the UI problem. The off line UI problem is not very straight forward because, do your users care or do they just want it to work? And in some cases you might explicitly want to say I'm going off line. And that's probably not as interesting as the, okay, let the user know they're working off line because their internet connection dropped or that they're not online. But don't force them to think about it too much. We have a basic storage provider. You've saw the Dojo storage provider stuff a little bit before. This ties into it in very much the same way.

Google provides a sequel database back end so they use SQL Lite in the browser as an extension and so we provide Dojo dot SQL to read and write from a local database. There's also, since Firefox 2 and, I guess Firefox 2 and 3 are it right now. Maybe does Safari have that, local DOM storage? I don't think so.

[Alex Russell]

I don't think so.

[Dylan Schiemann]

Okay. Local native browser storage that you can read and write to. So just think of it as a very very large cookie that you can natively write to on your file stem. And then there's of course the fallback mechanism for all of the other browsers which is Flash.

Flash is always supported larger than your 4K cookies and we've used that for a couple of years now. So we have a few very simple, very straight forward, very easy to remember API's for doing this. There's Dojox dot off dot on off line and on online. They sound a little strange because it's off online and off on online. Yeah. (Laughter)

[Dylan Schiemann]

It's intended to be very consistent with the way browsers name events with this on scheme. We also have mechanisms for cashing files, refreshing cache, not particularly interesting until you're really digging into it.

[Alex Russell]

We're going to be providing the Dojo Offline API's in the data that we're shipping next week so you'll be able to start playing with them there. We have them mostly ported to Dojo 0.9. We did the initial work on Dojo 0.4 and we wrote our own proxy before Google Gears was available.

So we've been in the process of porting from that proxy and the testing workload to refine the API's to work in toggle gears and we hope very soon that we'll have a gears implementation that works with Safari 3 beta. I'm hoping very much that Google gets that done. Right now I think we are gated on Google to that.

[Dylan Schiemann]

Yes.

[Alex Russell]

So one of the other edge of the web features that we're really excited about is the ability to have the server push events to the client. Dojo has for, I think the last six months or so at least, had an implementation of a Bayeux client. Bayeux is this protocol that works by supplying with some other server vendors, a bunch of the people in the Java community, some Pearl people, and it's a JSAN based publish subscribed notification protocol which provides semantics that are above the wire level. So if you've seen XMPP's HTTP bind, that specifies a bunch of wire level stuff. HTTP works this way.

You'll do this and this and get this back. We're kind of trying to extract those from each other so that you know you're going to get JSAN over it and that whatever happens on the wire doesn't really matter to you. You've got some simple API's initialize, publish, and subscribe, which allow you to set up connections, set up listeners, and publish stuff to those listeners so long as it can be serialized to JSAN. And so we've been shipping this for a couple of releases in Dojo. The spec for Bayeux is firming up right now.

We expect that we're going to have a 1.0 spec any week now but it's not done quite yet. And we're still waiting on the servers to get upgraded. But we have some really good numbers here. And the reason that we have to have separate servers, the reason that we have to have Python servers or just specialized Java, Jedi, and Grizzly, or Perl on the Perl side, is that leaving lots and lots of zombie connections open, which is what is required to get this low latency data to the server done right, requires that we be able to not consume huge amounts of memory every connection that gets instantiated and gets left open. So these servers are written with a synchronous I/O mechanisms underneath them and we're not just wanting threads or processes per instance. So

[Dylan Schiemann]

Well, it's also that today's common web servers are not optimized for this. So a Comet server is optimized for opening long lived connections and a typical web server like Apache is optimized for opening and closing as many connections as quickly as possible. And so it's a very different optimization pattern and hence the need for very specialized

[Alex Russell]

Well let's look at the user experience then.

[Dylan Schiemann]

All right. The demo please.

[Alex Russell]

So, we put together a little Word Press plug in based on the can you actually size this so we can see both windows?

[Dylan Schiemann]

Yeah. Oh both windows.

[Alex Russell]

We put together a little Word Press plug in based on Cometd, the Python implementation of Cometd, although it doesn't matter which implementation we use. We could use any implementation. It doesn't we don't care because the protocol doesn't matter. And no, it matters very much in that we don't have to care about it.

So we put together a little imlementation based on Dojo and on Cometd and a little bit of a Word Press plug in so that whenever you publish post to a web log that's got this plug in enabled, everyone else who's on the page can see it immediately, if you refresh the page and have a connection open. Yeah. Yeah.

So everyone who's on the page at the same time can sea what's going on. Obviously we could add status information, we could add global notification, but what we're doing here is we're reducing the latency in the conversation. We would have loved to have made this available, but we don't know what the IP address is and we didn't want to run this on a public network because we're going to get a huge number of comments on this pretty quickly.

(Laughter) >> There's a little bit more work to be done in terms of making this work with the guts of Word Press, but we will release the source code for this plug in today so that you can have comments for realtime comments for your blog. Your conversation can go live.

And this is stuff that we can do on top of what's in Dojo 0.9 already and what we're doing at the Cometd project. So we're really excited about this. Can we go back to the slides? As you saw, there's only three major API's. These are the three API's aside from Dojo dot require Dojox dot Cometd that we needed on the client's side to get this done. That's it. All right. We saw that.

(Laughter)

[Alex Russell]

So all the stuff that we're trying to do here is all about responsiveness. We're trying to build more responsive web interfaces. We're trying to build a better experience that gives the users what they want while waiting less. And so while we've been doing Dojo's the work for Dojo 0.9, we've had to rethink a lot of what we've done in the past in order to make sure that we're focusing on the responsiveness of the experience. And one of the big problems with doing anything in JavaScript is that we have to wait until the JavaScript interpreter and the DOM that we're based on are already bootstrapped.

We have to go and we have to get the code off the wire, we have to get the DOM that we need, we have to get the HTML, CSS, and JavaScript off the wire to do what we need, we have to have it all substantiated, we have to be parsed, and then we can start doing stuff. So anything we can do in HTML, anything we can defer down to HTML is a huge win. And so that makes the onus on JavaScript browser, excuse me, browser vendors for cashing and client library vendors for size reduction huge.

Anything we can't we don't send is the best bites that we could send. So we're trying to make sure that in Dojo 0.9 we're not taking much of a hit in terms of either getting the stuff off the wire, getting out of the cache, or making sure that when we construct the UI's it's as fast as possible. And let's look at how we're doing.

When we're talking about optimizing JavaScript in general, there's a bunch of stuff, or web pages just in general, there's a bunch of stuff that we can throw at the problem. We can take out white space, we can take out comments, we can remove variable names; we can shorten variable names in JavaScript. We can do much the same thing in CSS if we have the whole page at our disposal. And if we get really really lucky we might be able to remove some dead code if we got good compiler technology.

And once we get the stuff off the wire, we have to make sure that if we're using some exotic packing system, like Dean Edwards Packer, we're not taking a lot of time in decompressing the system. So we have to make sure that there's this there's a valid trade off between the size and the wire and the time it takes to decompress. If we're on a really fast local connection and it takes me ten milliseconds to grab something off the wire, but 100 milliseconds to unpack it, that's clearly not a good win.

So and G zip is our ally. We want to make sure that anything we're sending across the wire is G zipped. But at Dojo, we can't verify or force you to G zip anything. So what we're doing is providing the smallest possible downloads we can and we have a build system to do that. So yeah. And when we make builds...can I just drive?

[Dylan Schiemann]

Yeah. Sorry. (Laughter)

[Alex Russell]

Sorry.

[Dylan Schiemann]

You have too many (inaudible).

[Alex Russell]

When we make builds, what we're talking about is taking a set of related JavaScript components, using the package system smarts. The package system knows what you need if you tell it. It can go and it can find out the dependencies that you need in the order you need them and lay them all out linearly so that you could get one file, reduce the number of HTTP requests you're making, strip the comments and white space all at once, and then G zip one file and make sure that one file is cashed.

That means that if we have a poorly configured HTTP server, we don't necessarily have to worry about having our 304 setting correctly if we've only get one file to go check as opposed to lots of little files. And we're not blocking on initial page load for a bunch of stuff that has to happen synchronously because getting JavaScript almost always happens synchronously. So we've had a build system in Dojo to help solve this problem since probably the earliest versions. I think 01 had something like this and that was three years ago.

We've upgraded the system significantly for 0.9. It used to use ant. We hate ant and we're fixing it. So the entire build system now is pure Java and JavaScript. So Java 6 includes Rhino and we're using a custom version of Rhino that ships when you get the Subversion check out. So you don't have to go get any other tools aside from a Java runtime environment, which you've already got installed on OS 10. So you can go and you can grab Dojo Dojo source check out.

We're also done a web based build tools so that if you know what you need, you can go and you can make that stuff yourself. And we've got this idea of roll ups in Dojo 0.9, or layer files as we're calling them. Dojo Dojo dot JS always means one thing. It means one set of base very rich functionality for doing things like event connection, topics, the package system, style manipulation, animation, gosh, AJAX, a whole bunch of stuff you might need.

[Dylan Schiemann]

It's the stuff you need 90 percent of the time rather than the stuff you need 2 percent of the time.

[Alex Russell]

But Dojo has a whole other universe of stuff that you don't necessarily need all the time. And we don't have to make it. We don't want to have to make it slow for you to go get that stuff when you know you need it. So the build system can roll up the other packages that are available in Dojo and it can roll up your own code.

The build system also, because widgets, as we saw in a little bit here, can have external files which specify their UI, the build system is savvy about those. It can take those files, intern them as strings in the JavaScript file that you're getting so that everything you would have made separate requests for before gets rolled into a single file. And we have this idea of layered builds so that you know in your application. So before, we had the ability to create one big JavaScript file.

And if I'm heavy in development on an application that's live and I change one little function kind of over here on the right, I don't want to have to go cache churn for all of my clients all of the stuff that I had. I want to make sure that users are getting as much use out of their cache for all the other stuff that didn't change as we can possibly get.

So being able to require stuff dynamically, which is what the package system can do. I can call dijit dot require at any time and get any package that Dojo makes available, but it has to happen synchronously. So I can do that after the page is loaded if I know that I want to defer execution. Or I have to stuff it all up front. There's no kind of middle ground in Dojo 0.4.

What Dojo 0.9 provides is the ability to layer those things out so that I know if I've got Dojo dot JS and then some common stuff in my application, I can package those into two files and those two files can always be loaded. And then if I've got page specific stuff I can break it out. And I can itemize or delay or load stuff opportunistically, in whatever way I know will make my application fastest. This is a huge win and it's all available in the beta we'll be releasing next week.

[Dylan Schiemann]

You should talk about the CDN.

[Alex Russell]

And let's look at a demo of the build system. Also, yeah, Dylan raised a great point.

[Dylan Schiemann]

You (inaudible).

[Alex Russell]

So

[Dylan Schiemann]

You can also get the current version of Dojo dot JS from the AOL content distribution network. So what you can do is you can off load the requirements of having to download Dojo to AOL and at the same time every other site that uses Dojo can cache the same copy of Dojo dot JS. So you can save your users some download, you can save yourself some bandwidth cost, and you get the benefits of Dojo. They're just the same.

So this is the Dojo build system and it's just command line command. It's, you know, Java, pull in a jar file, define a few properties for your build. In this case clean cleans up the file system, release is going to create a release build. Are you going to do intern strings?

[Alex Russell]

No.

[Dylan Schiemann]

No? Okay. You pick a profile. In this case the profile's named 0 dot 9. The profile itself is a JavaScript file that defines the dependencies or layers that you want. You see some output.

[Alex Russell]

And the only thing you have to change when you're using the build versus the source of one of these distributions, is where you're pointing at your JavaScript file, your initial Dojo dot JS file. Dojo knows where it got loaded from so that it goes and it auto discovers where it got loaded from. So your Dojo dot requires don't have to change. You just point it at the release directory that Dojo dot JS that's being built inside that release directory and don't necessarily even have to worry about your stuff.

So let's go look at a really simple layer file and look at an application that uses it and look at the before and after for the performance of loading stuff across the wire using the build system versus not using the build system. And again, it's worth repeating that you can use this system for your own code. You can optimize your own code and your own modules and using modules in Dojo is really straight forward.

You just put in a directory; you just say Dojo dot provide and require at the top of your file. That's it. And if we look at what we've got here, we can see that if I go into I'm going to have to use Firebug, so I'm going to have to use Firefox here. I apologize.

If I go into this Dojo check out, I've got a file here called three pane dot HTML. And this is just going to create a really simple three pane tabs you. It's got, you know, a data bound tree, it's got some accordions, you know, just basic stuff. Not a lot of mark up.

But if I look at what I had to pull across in order to get that done in the source version of Dojo, I'm pulling in a lot of files. And as you can see from Firebug, they're all synchronous. That's a lot of stuff that I may or may not want to be pulling in synchronously. And it contributes significantly you can see to the loading the page.

So what does a build do for us there? If we look at the source in this page, we can see that we're pulling in two files that really matter, Dojo dot JS and dijit dot JS. And what I'm going to do here is I'm going to switch to using the built versions of those and we're going to go and look at the new network trace.

So I'm going to go modify my file here. I'm just going to comment that out. And I'm just going to again, it's only pulling in from the same directory structure, same names. I'm just pulling in the release slash whatever versions of those of that stuff. I'll come in here and I'll clear the cache just for kicks. Nothing up my sleeve. Oh, not that. Fire that back up.

It's actually a little bit noticeably faster. But what we see here is before G zip, all of these numbers are before G zip. What we're seeing on the wire here is unpacking. What we're seeing on the wire here is significantly fewer requests. All that stuff got rolled up into two files, aside from the stuff that is CSS and images.

So based on this, I've got a layer file for dijit, which are my widgets, and then I've got a layer file for Dojo dot JS. And how did I declare that stuff? What kind of magic does it require to make my application that fast? So I can see in dijit dot JS, all I'm doing here is calling require on a bunch of stuff. That's it. I'm just pulling in those modules here. That's all I'm doing. Okay. And in fact, I'm pulling in modules that I'm not even using in this example.

In util build scripts profiles script there's a set of these profiles and I'm going to pull up the 0.9 profile which is what I just built. And Dojo dot JS is always implicitly build. Dojo dot JS is always the same thing. It always means that that nicely curated set of well tested, high performance functions that we know that you're always going to need. And you can specify a set of layers in your dependencies object. And these layers take an output name, the name of the file that we're going to generate. In this case we're just replacing the one that was already there.

We could output it to someplace else. We use the package system to load up what it is that this is going to require and what's worth noting here is that if I've got multiple dependencies or multiple, excuse me, multiple layers, they can specify each other. And what's going to get baked into each one of those layers is only what wasn't covered by the previous layers that I specify and everything that they require. So this system can be used to layer your requires just the same way that the run time package system only loads the stuff that it knows that it needs.

[Dylan Schiemann]

So it never builds in the same code twice, even if you require it more than once.

[Alex Russell]

And so if I want to load in say, stuff from my app, I just specify that I'm going to pull in the my app stuff into my and it's going to live alongside my Dojo directory. So that's all it takes to implement your own layers and Dojo and use the build system to to optimize your application for deployment. You don't have to change any of your code, you don't have to change the way you're using it, you don't have to change the way you're using Dojo; you just make a build.

And that's the result. And these these are non G zip numbers. If I go and I pull down a G zip version of that, it's probably going to be close to 20 K on the wire for the Dojo dot JS and that 200 K is probably going to be closer to 50 for all those widgets. And in fact there's a lot of widgets here that I'm not even using on this page. There's like the rich text editor and a whole slew of tab pane and widgets that I'm not using.

So. All right, that's the build system. Can we go back to the slides? Thanks. So Dojo has been accused of being kind of an elephant in the past, kind of big, kind of clunky. It's got a lot of stuff. It's always been possible to know that you had something that you wanted to do and Dojo could do it.

You always had that kind of inkling in the back of your mind that Dojo could do it, but whether or not you knew what the exact function was going to be called. And in Dojo 0.9, we're trying to take that inkling that you've had and make it very explicit that yes you can do it and here's how you find it.

We've been at this a long time. We started Dojo as an amalgamation of three other pre existing JavaScript toolkits and have been building from there. And we've been able to implement a lot of features and a lot of flexibility. And that's kind of like the cost of understandability.

It's been very difficult to know, when you get a Dojo download, what's there, how do you get what you want, what's even possible? And so we're taking the opportunity to step back and for the last six months we've been thinking about every API, questioning every design decision, removing flexibility in places where you don't need it, taking the crud out of the system, removing all the backwards compatibility shims, and only providing you with nicely focused API's that get your job done without having to worry about the past. And the results are pretty impressive.

So these are two roughly equivalent functionality builds, although Dojo 0.9 base does better than the 0.4 AJAX build because it also includes Dojo dot query and the new high performance style functions. As you can see, at almost every axis between the build size and the G zip size, and the uncompressed size, it's half the size. Dojo dot JS on the wire for your application in a well tuned app is about 20 K. That's the size of an ad, and it's cashed. You only need it the first time.

So what about a more full featured thing? What about Dojo dot JS plus the basic widget stuff, that dijit file that only includes just the widget system? And Dojo 0.4 uncompressed, you were pulling in almost a half a meg of JavaScript. That's a lot for a browser to chew on.

But the build did a really great job. It stripped out comments, it shortened variables, it got us down to less than half of that. And G zipped on the wire, it was 50 K. We're still half the size, roughly half the size at almost every axis here at Dojo 0.9 for equivalent or better functionality. We're really happy with these numbers.

So how does it perform in terms of run time speed? So what we're looking at here is the I apologize, they're blue and purple. The blue ones are the Dojo 0 point the mark up driven numbers. So what it takes to parse the page out. And then the purple ones are building 100 buttons programmatically. And what we can see is that IE is a dog, Firefox is somewhat better, and no matter what browser you're using, Dojo 0.9 really kicks butt.

One of the ways that we've improved the speed of the system is just by doing less to get the same result. So one of the ways that this is visible is by looking at the number of objects that get allocated whenever we pull in Dojo, or some variant of Dojo, and see how much we're doing and how many objects we have to create. Again, there's roughly half as many objects for similar functionality in Dojo 0.9 versus Dojo 0.4. We couldn't be happier about that.

And in particular, we couldn't be happier about Dojo 0.9 on WebKit. WebKit kicks ass. I know that that's probably not kosher for me to say, but WebKit is amazing. The Safari 3 beta is probably the fastest browser on the planet for DHTML stuff and we tend to show you how.

Last year, or earlier this year, Brian Breen (assumed spelling) went ahead and used the Dojo charting engine so client side charting is part of Dojo. He went ahead and used a charting engine to benchmark a bunch of the stuff that we were seeing just kind of just guessing at that we'd seen between the WebKit nightlies and the other browsers that are

[Dylan Schiemann]

available. What he did is he created a test site that the whole world could go to and hit and then he recorded all of the average speeds from basically every user that went to this site. And then collated the numbers, provided them online for us.

[Alex Russell]

So drawing a chart in this chart the performance metrix chart in WebKit and this is on the 0.4 branch. This is not necessarily a huge speed gain because of Dojo 0.9. On the 0.4 branch, drawing it was three tenths of a second. On IE, we're looking oh, excuse me. It's, no, 30 milliseconds, not three tenths of a second. On IE it's almost three tenths of a second. It's almost ten times as slow to render the exact same thing on Internet Explorer due to its kind of lame and slow VML implementation.

Opera is also an outstanding browser and it gets pretty close, but WebKit, far and away, takes the cake in terms of raw performance. If we look at this on another axis, we can see that we didn't have Safari 3 beta for Windows at the time so we couldn't bench mark this, and we would love to get those numbers. But despite the fact that there are rumors of the the painting path on OS 10 being a little bit less performer versus Windows, it's clearly not true. The tuning that's gone into WebKit is astounding. It's faster than all commerce across all browser across all OS's.

And the same thing is true if we look at different builds and different versions of those same browsers. We're seeing that as WebKit got better, the performance stayed roughly in line with where it was. Yes. But what we care about at Dojo is how fast it takes to build up our stuff.

[Dylan Schiemann]

Yes.

(Laughter)

[Alex Russell]

So the fact that it's just generally roughly a lot faster is awesome for you as a user, but we want to make it so that when you're building apps for your user with Dojo that you're getting the best experience possible, and WebKit is delivering in huge fashion.

This is a this is a benchmark that we've checked into both the 0.4 and 0.9 branches. You can go run it yourself and verify our results. And what we're seeing here is that to generate 100 buttons programmatically is less than a tenth of a second. You can paint more than a thousand widgets a second in WebKit.

To give you some basis for comparison, the upper limit for the number of widgets that we could reasonably paint in an application on the 0.4 branch on any browser was roughly two or 300. Now we're looking at doing thousands, depending on whether or not you're building them in response to user action. You can provide really really rich UI's. Now obviously a thousand buttons isn't really necessarily a good UI. (Laughter) >> Alex: But you can do it.

(Laughter)

[Alex Russell]

The calendar widget is significantly more taxing in terms of the number of DOM nodes that we're creating. A button is like ten DOM nodes to get all the accessibility and the theming and style stuff all done. So the calendar widget is huge in terms of nodes.

[Dylan Schiemann]

It's about a hundred nodes.

[Alex Russell]

Well, what we've got here is is WebKit totally kicking everyone's butt. We're more than three times as fast versus all the other browsers. And these are relatively these are on the same box. This is just parallel so we've got VXT technology on the IE numbers. There's a little bit of hypervisor overhead, but it's not enough to make up for these numbers. This is borne out by real world stuff.

So at the end of this, we want to thank you for coming today to hear about Dojo 0.9. We're going to be making a beta of 0.9 available next week and you'll be able to start playing with all the stuff that we talked about and have shown. You can get it from Subversion. We're an open source product.

It's free to use. There's no GPL licensing. It's all BSD so you can use it in your commercial projects; you can use it for your open source stuff. There are no restrictions and we have code lineage so that you know when you're using Dojo, it was clean. It's good enough for IBM, and it's good enough for Apple, so we hope it's good enough for you.

[Dylan Schiemann]

Oh yeah, one more thing.

(Laughter)

[Dylan Schiemann]

Skip to the next slide.

[Alex Russell]

George?

[Dylan Schiemann]

George, where are you?

- George: Thanks guys.

(Applause)

George: Dylan, Alex, that was awesome. Thank you very much. So actually given the time that we're at right now, does the room manager want to make any announcements? Because if not I think that we should skip this.

How many in the room saw the iPhone session at 3:30? The rebroadcast? Excellent. Okay, basically I was going to spend some time to go through reiterating the best practices for creating AJAX applications on the iPhone, but I do want to open this up for some Q and A. This is the end of a very long week.