I recently gave a State of the Open Web talk as part of the Google Developer Days overseas, in Italy, Russia, the Czech Republic, and Israel (I’m getting over a 10-hour jet lag right now - whew). The talk description:
“Come learn about the state of the Open Web, what it is, and why it is so important. In this presentation you will learn about the latest Open Web technologies, including the Canvas tag, Web Fonts, SVG, HTML 5, and see demos, code snippets, and the state of their implementations across browsers. Discover what you can use today (more than you’d expect!) and what remains to be done.”
[Disclosure: I work for Google on the Open Web Advocacy team]
Google Chrome uses a library called Skia, which is also the graphics engine behind Google’s Android mobile OS. The two projects share code that implements WebKit’s porting API in terms of Skia. Google Chrome also uses Skia to render parts of the user interface such as the toolbar and tab strip. I’m going to talk about some of the history that led us to choose Skia, as well as how our graphics layer works.
We moved the I/O onto a number of background threads which allow the user-interface to proceed asynchronously. We did this for large data sources like cookies, bookmarks, and the cache, and also for a myriad of smaller things. Writing a downloaded file to disk, or getting the icons for files in the download manager? The disk operations are being called from a special background thread. Indexing the contents of pages in history or saving a login password? All from background threads. Even the “Save As” dialog box is run from another thread because it can momentarily hang the application while it populates.
To achieve the streamlined feel we were after, we knew we would have to cut some things, and while we had our own intuitions about what was and wasn’t useful in current browsers, we had no idea how those ideas matched to reality. So in typical Google fashion, we turned to data; we ran long studies of the browsing habits of thousands of volunteers, compiled giant charts of what features people did and didn’t use, argued over and incorporated that data into our designs and prototypes, ran experiments, watched how our test users reacted, listened to their feedback, and then repeated the cycle over and over and over again.
Even the the more subtle parts of our first-level UI were subjected to similarly intense scrutiny - “what shade of blue best suits XP users”, “should the tabs start 18 or 19 pixels below the top of the window?”, “what’s the correct offset between our buttons?”. The answers to these questions were debated and tested for our entire development cycle, and we saw that opinions consistently differed greatly depending on whether we had been Windows 3.1, OS7 or even NeXT users and developers.
Google Chrome’s multi process architecture allows for a lot of flexibility in the way we do security. The entire HTML rendering and JavaScript execution is isolated to its own class of processes; the renderers. These are the ones that live in the sandbox. We expect to work in the near future with the plug-in vendors to securely sandbox them as well.
I have to admit that I personally wish Cairo was chosen, as having the Google engineers behind that project would have been amazing, and benefit would be had for all of the applications that use it.
Amongst the reactions to Google’s release of Chrome was the developer’s howl of pain at the thought of another major browser on which to do compatibility testing. Google’s generally asserts that Safari compatibility results should be the same as Chrome’s, but Nathan Hammond stumbled across a divergence that he finds troubling and which Google shows no inclination to fix. Says Nathan:
There exists a bug in Google Chrome that breaks most history managers. Most all current historymanagers rely upon form-based storage to repopulate their history stack after navigating away from and returning to the present document object, but Chrome doesn’t refill form fields when that happens. The result of that is that Google Chrome is currently incompatible with websites using the current generation of history management plugins, and, if their issue tracker has anything to say about it, will remain that way. The bug was closed as “wontfix” due to a misunderstanding. However, it still needs to be addressed to meet the goal of Chrome as I heard at The Ajax Experience 2008: a goal of not fracturing the web and creating yet another browser we developers have to test in and code around.
It is really exciting to see the level of pace that browsers have been setting recently, especially with respect to performance.
I have been able to keep in sync with Google Chrome the new browser, and Chromium, the open source code-base it comes from. There are a couple of innovations that have been great to see such as the multiple process model for tabs and windows, the unified tab and search functionality, and at the core, V8.
V8 is the super-speedy JavaScript VM by Lars Bak of Sun HotSpot fame. When you run JavaScript benchmarks on this puppy, you see very speedy responses indeed. The V8 part of the comic says it well:
The breakthrough of having hidden classes to look at structures and work out the shared information (e.g. object Foo looks like a Person). Once you have that data, you can optimize in the same way you would class systems. V8 improvements consist of:
Compiler: Instead of using interpretation, JavaScript gets compiled down to native code
Inline caching: Optimize for accessing, and function calling
Very efficient memory management system
What version of JavaScript? “V8 implements ECMAScript as specified in ECMA-262, 3rd edition, and runs on Windows XP and Vista, Mac OS X 10.5 (Leopard), and Linux systems that use IA-32 or ARM processors.”
Some of the core technology is also exciting to geeks. For example, as this code is operating system neutral we use the Skia Graphic Library (SGL) used by the Android team.
What about the process manager? John Resig has interesting thoughts on that with the rub: “The blame of bad performance or memory consumption no longer lies with the browser but with the site.”
This is all great to see. Not only is this just the beginning for Google Chrome, Chromium, and V8 (I am dying for a Mac version!), but the other browsers are keeping pace too. The end result is a better Web for users, and a higher quality of product for developers to build against!
I have seen the GWT team working very hard indeed on GWT 1.5, and they must be very happy to see the final release shipped and complete:
GWT 1.5 delivers what we think are an impressive number of improvements, about four hundred issues if you’re counting. We’re also happy that one of those is issue 168, our most-requested feature, Support for Java 5.
The high level new feature sets are:
Java 5 language support and enhanced JRE emulation
Performance optimizations and easier JavaScript interop
Prettier widgets, better DOM, accessibility, and bi-di
The project is a collection of libraries that provide Java language bindings
and API specific ‘plumbing’ for some Google JavaScript APIs. The goal is to
make it easy for developers to use these JavaScript APIs with GWT. Libraries
available at this time include a new version of Gears, as well as new
libraries for Gadgets and the Google AJAX Search API.
Gears 1.1 Library
A new version of the Gears library is available. In addition to the earlier
version’s support for the Gears LocalServer, Database, and WorkerPool, 1.1
adds integrated support for offline applications and updated sample
applications. The bindings have also been refactored to use GWT 1.5
JavaScript overlay types and a new package hierarchy.
Gadgets 1.0 Library
The Gadgets library simplifies gadget development with GWT by automatically
generating a Gadget specification from Java source and inserting a selection
script in the specification much like a regular GWT project. After compiling
your gadget with GWT, all files are in place to publish your gadget. This
version currently supports the legacy Gadgets API based on the _IG_…
namespace.
Google AJAX Search 1.0 Library
The Google AJAX Search API lets you put Google Search in your web pages,
including Web, Local, and Multimedia searches. This library allows you to
access the API from Java code compiled with the GWT compiler without having
to write additional JavaScript code.
Last week I wrote a simple WhereAreYou? application that used the Google Ajax APIs ClientLocation API to access your location via your IP address.
At the same time, we announced support for the Gears Geolocation API that can calculate your address using a GPS device, WiFi info, cell tower ids, and IP address lookups.
Add to all of that, the W3C Geolocation API that Andrei Popescu of the Gears team is editing. You will notice that it looks similar to the Gears API, with subtle differences. The ClientLocation API is quite different.
To make life easier, I decided to put together a shim called GeoMeta that give you the W3C Geolocation API, and happens to use the other APIs under the hood.
If you have the Geolocation API native in your browser (no one does yet, future proof!) that will be used. If you have Gears, that API will be used, and finally, with nothing the ClientLocation API will be used behind the scenes.
To you the API will look similar:
// navigator.geolocation.getCurrentPosition(successCallback, errorCallback, options)
navigator.geolocation.getCurrentPosition(function(position) {
var location = [position.address.city, position.address.region, position.address.country].join(', ');
createMap(position.latitude, position.longitude, location);
}, function() {
document.getElementById('cantfindyou').innerHTML = "Crap, I don't know. Good hiding!";
});
At least, that is what I would like. Unfortunately, there are a few little differences that leak through.
The W3C API only seems to give you a lat / long, so you have to do the geocoding to get address info
The Gears API gives you an additional gearsAddress object attached to the resulting position object. This can contain a lot of information on the resulting area (street address to city to …) however for certain providers the API returns that as null, the same as the W3C standard
That gearsAddress object has slightly different information from the address data that the ClientLocation API returns. NOTE: I would love to see this just called ‘address’ to help the shim.
To give you control when you need it, you can ask the navigator.geolocation object what type it is. navigator.geolocation.type will be null if it is native, but ‘Gears’ or ‘ClientLocation’ if a shim kicks in. You can also check navigator.geolocation.shim to see if it is augmented code.
Implementation
There is some fun implementation code in there if you poke around. For example, for the ClientLocation API, when you make a call, it will be added to a queue if the Google Loader hasn’t fully loaded yet, and it will kick off that call when finished. Dealing with dynamically creating <script src> as a loading mechanism sure is fun!
I like the idea of jumping straight to the W3C standard and updating the shim as the APIs change. That way, when browsers catch up, the code will still work using the native APIs and you don’t have to change a thing.
I also hope that we get general reverse geocoding in place, which would enable me to even take the native “standard” and strap on useful address info to the bare bones lat/long.
Google and Adobe have been working on improving the indexing of Flash applications. In the past we could simply look at the SWF files and try to grab strings out of them, but there was zero context.
To go further Google uses the SWF Searchable work from Adobe to be more of a ‘human’ actor on the application.
This is what it doesn’t do:
Googlebot does not execute some types of JavaScript. So if your web page loads a Flash file via JavaScript, Google may not be aware of that Flash file, in which case it will not be indexed.
We currently do not attach content from external resources that are loaded by your Flash files. If your Flash file loads an HTML file, an XML file, another SWF file, etc., Google will separately index that resource, but it will not yet be considered to be part of the content in your Flash file.
While we are able to index Flash in almost all of the languages found on the web, currently there are difficulties with Flash content written in bidirectional languages. Until this is fixed, we will be unable to index Hebrew language or Arabic language content from Flash files.
This is good news for all rich applications. One of the common worries when it comes to richer application development is “what do search engines see” and we sometimes see people go back to the simpler world just to make that happier. With the search engines stepping up themselves, we can go back to writing applications that make sense for our human users, and hope that the computers catch up. Of course, we always have to do so in a practical way.
Some good stuff came out from my employer. First, we have the Gears 0.3 release which includes support for Firefox 3! I have been using it for awhile, and it has been great. The team wanted to get it out before the Firefox 3 launch (planned for June 17th). A plugin like Gears can get deep into browser internals, so it is a challenge to keep up to date as APIs change in beta releases, so it is great to be out there now and I we will take a close look at the final release!
I just got to announce the Google AJAX Libraries API which exists to make Ajax applications that use popular frameworks such as Prototype, Script.aculo.us, jQuery, Dojo, and MooTools faster and easier for developers.
Whenever I wrote an application that uses one of these frameworks, I would picture a user accessing my application, having 33 copies of prototype.js, and yet downloading yet another one from my site. It would make me squirm. What a waste!
At the same time, I was reading research from Steve Souders and others in the performance space that showed just how badly we are doing at providing these libraries. As developers we should setup the caching correctly so we only send that file down when absolutely necessary. We should also gzip the files to browsers that accept them. Oh, and we should probably use a minified version to get that little bit more out of the system. We should also follow the practice of versioning the files nicely. Instead, we find a lot of jquery.js files with no version, that often have little tweaks added to the end of the fils, and caching is not setup well at all so the file keeps getting sent down for no reason.
When I joined Google I realised that we could help out here. What if we hosted these files? Everyone would see some instant benefits:
Caching can be done correctly, and once, by us... and developers have to do nothing
Gzip works
We can serve minified versions
The files are hosted by Google which has a distributed CDN at various points around the world, so the files are "close" to the user
The servers are fast
By using the same URLs, if a critical mass of applications use the Google infrastructure, when someone comes to your application the file may already be loaded!
A subtle performance (and security) issue revolves around the headers that you send up and down. Since you are using a special domain (NOTE: not google.com!), no cookies or other verbose headers will be sent up, saving precious bytes.
This is why we have released the AJAX Libraries API. We sat down with a few of the popular open source frameworks and they were all excited about the idea, so we got to work with them, and now you have access to their great work from our servers.
Details of what we are launching
You can access the libraries in two ways, and either way we take the pain out of hosting the libraries, correctly setting cache headers, staying up to date with the most recent bug fixes, etc.
The first way to access the scripts is simply be using a standard <script src=".."> tag that points to the correct place.
For example, to load Prototype version 1.6.0.2 you would place the following in your HTML:
You will notice that the version used was just "1". This is a smart versioning feature that allows your application to specify a desired version with as much precision as it needs. By dropping version fields, you end up wild carding a field. For instance, consider a set of versions: 1.9.1, 1.8.4, 1.8.2.
Specifying a version of "1.8.2" will select the obvious version. This is because a fully specified version was used. Specifying a version of "1.8" would select version 1.8.4 since this is the highest versioned release in the 1.8 branch. For much the same reason, a request for "1" will end up loading version 1.9.1.
Note, these versioning semantics work the same way when using google.load and when using direct script urls.
By default, the JavaScript that gets sent back by the loader will be minified, if there is a version supported. Thus, for the example above we would return the minified version of jQuery. If you specifically want the raw JavaScript itself, you can add the "uncompressed" parameter like so:
Today we are starting with the current versions of the library, but moving forward we will be archiving all versions from now onwards so you can be sure they are available.
Here I am, talking about what we are doing in two short slides:
The Future
This is just the beginning. We obviously want to add more libraries as you find them useful. Also, if you squint a little you can see how this can extend even further.
If we see good usage, we can work with browser vendors to automatically ship these libraries. Then, if they see the URLs that we use, they could auto load the libraries, even special JIT'd ones, from their local system. Thus, no network hit at all! Also, the browser could have the IP addresses for this service available, so they don't have the hit of a DNS lookup. Longer lived special browser caches for JavaScript libraries could also use these URLs.
The bottom line, and what I am really excited about, is what this could all mean for Web developers if this happens. We could be removed of the constant burden of having to re-download our standard libraries all the time. What other platform makes you do this?! Imagine if you had to download the JRE everytime you ran a Java app! If we can remove this burden, we can spend more time flushing out functionality that we need, and less time worrying about the actual download bits. I am all for lean, but there is more to life.
Acknowledgements
I want to acknowledge the other work that has been done here. Some libraries such as jQuery and Dean Edwards Base were already kind of doing this by hot linking to their Google Code project hosting repository. We thought this was great, but we wanted to make it more official, and open it up to libraries that don't use our project hosting facilities.
Also, AOL does a great job of hosting Dojo already. We recommend using them for your Dojo needs, but are proud to also offer the library. Choice is good. Finally, Yahoo! placed the YUI files on their own CDN for all to use.
Doctype is an exciting beast, and for many reasons. Having a place to collect this data is key, and as I said yesterday, I can't wait to see it grow as an open resource.
The other cool part of Doctype is that there are tests to backup claims. This seems like a "no brainer" as some of my 'sherman' friends would put it, as it is the corner stone of science.
Mark Pilgrim has released Google Doctype, an open encyclopedia and reference library. Written by web developers, for web developers. It includes articles on web security, JavaScript DOM manipulation, CSS tips and tricks, and more.
The reference section includes a growing library of test cases for checking cross-browser and cross-platform compatibility.
This is just the beginning for the ambitious project, which is open source, and open licensed (Creative Commons). Now it is out there we, the developers, have the option to add valuable data to grow the corpus.
Congrats to Mark on the launch. I know that it has been a huge amount of work for him, and I am excited to see it out there. Below is Mark talking about the project:
You may also notice the document reader application, which is driven by GWT.
Today we have Bruce Johnson of the GWT team talking to us about GWT 1.5. He discusses the new features, such as the long awaited Java 5 language support, performance improvements, and much more.
It is very nice to take an application, run it through the new GWT 1.5 compiler, and get an instantly faster running application "for free".