Thursday, September 3, 2009

The Weekend of Wet

Cancel your hike on Saturday. Get a good book (hint...a suggestion is on the upper right of this page). Don't water your garden tomorrow. The weekend of wetness is coming. And the end of any serious threat of wildfires over the Northwest.


But not tomorrow. A weak front is approaching right now (see image) and could bring some light rain to the coast, but only some sprinkles will hit over the interior.

But wait until Saturday, when a moderate front..with plenty of moisture... will reach us.
The rain from the front will approach the coast in the early morning hours and the western lowlands between 7 and 9 AM. The three hour rainfall ending 11 AM is shown below. The front will move through during the day, bringing rain to the Cascades and even some showers to the east of the crest. Take a look at the 24-h rainfall ending 5 PM below. Perhaps a 1/4 to 1/2 inch over the lowlands. Not a good day for a hike in the Olympics. You could get away with a hike on the lower eastern Cascade slopes if you go early.
But wait. The fun doesn't stop there. The front moves through Saturday evening, followed by a short break in the action. Then an upper trough moves in bringing more showers to the region on Sunday. Take a look at the precipitation for the 24-h ending 5 PM on Sunday below. Plenty of rain over the entire state..with particularly heavy rain on the SW side of the Olympics...roughly two more inches. And eastern Washington gets enough to wet things down.
And did I mention the winds? A surface low will accompany Sunday's trough...bringing windy conditions over the ocean and along the coast (see graphic). And 25-35 kt southeasterly winds will develop over NW Washington.
Time to find your rain jackets that have been buried in your closet. You will need it. And one more thing...watch the driving. It has been fairly dry and there is lots of oil on the road. Add water and it will be slippery.

Gmail for Mobile HTML5 Series: Reducing Startup Latency

On April 7th, Google launched a new version of Gmail for mobile for iPhone and Android-powered devices. We shared the behind-the-scenes story through this blog and decided to share more of what we've learned in a brief series of follow-up blog posts. This week, I'll talk about how modularization can be used to greatly reduce the startup latency of a web app.

To a user, the startup latency of an HTML 5 based application is critical. It is their first impression of the application's performance. If it's really slow, they might not even bother to wait for the app to load before navigating away. Even if your application is blazing fast after it loads, the user may never get the chance to experience it.

There are several aspects of an HTML 5 based application that contribute to startup latency:
  1. Network time to fetch the application (JavaScript + HTML)
  2. JavaScript parse time
  3. Code execution time to fetch the data and render the home page of your application
The third issue is up to you! The first two issues, however, are directly correlated with the size of the application. This is a tricky problem since as your application matures, it will have more features and the code size will get bigger. So, what to do? Modularize your application! Split up your code into independent, standalone modules. Consider splitting each view/screen of your application and implement each new feature as its own module. This is only half the story. Now that you have your code modularized, you need to decide which subset of these modules are critical to load your application's home page. All the non-core modules should be downloaded and parsed at a later time. With a consistent code size for your startup code, you can maintain a consistent startup time. Now, let's go into some nitty gritty details of how we built an application with lazy-loaded modules.

How to Split Your Code into Modules

Splitting an application into individual modules might not be as simple as you think. Code that serves a common purpose/functionality should be grouped together and form a module (comparable to a library). As mentioned earlier, we selected which modules are critical to the home page of the app and which modules can be lazy-loaded at a later time. Let's use a Weather application as an example:

High Level Functionality:
  • A "Weather in my Favourite Cities" home page
  • Click on a city to view the cities entire week forecast
  • Weather data comes from an external web service
Possible Module Separation:
  • Weather data model
  • Weather web service API
  • Common UI widgets (buttons, toolbars, navigation, etc)
  • Favourite Cities page
  • City Weather Forecast page
Now let's say your users want a "breaking news" feature. No problem: just put the page, the news data API and the data model into a new module.

One thing to keep in mind is the dependency order of your modules. For modules that have many downstream dependencies, it might make sense to include them as part of the core modules.

How to Lazy Load the Modules

Option 1: Script as DOM

This method uses JavaScript to insert SCRIPT tags into the HEAD's DOM.
<script type="text/JavaScript">
  function loadFile(url) {
    var script = document.createElement('SCRIPT');
    script.src = url;
    document.getElementsByTagName('HEAD')[0].appendChild(script);
  }
</script>
Option 2: XmlHttpRequest (XHR)

This method sets up XmlHttpRequests to retrieve the JavaScript . The returned string should be evaluated in the XHR callbacks (using the eval(string) method). This method is a little more complicated but it gives you more control over error handling.
<script type="text/JavaScript">
  function loadFile(url) {
     function callback() {
      if (req.readyState == 4) { // 4 = Loaded
        if (req.status == 200) {
          eval(req.responseText);
        } else {
          // Error
        }
      }
    };
    var req = new XMLHttpRequest();
    req.onreadystatechange = callback;
    req.open("GET", url, true);
    req.send("");
  }
</script>
The next question is, when to lazy load the modules? One strategy is to lazy load the modules in the background once the home page has been loaded. This approach has some drawbacks. First, JavaScript execution in the browser is single threaded. So while you are loading the modules in the background, the rest of your app becomes non-responsive to user actions while the modules load. Second, it's very difficult to decide when, and in what order, to load the modules. What if a user tries to access a feature/page you have yet to lazy load in the background? A better strategy is to associate the loading of a module with a user's action. Typically, user actions are associated with an invocation of an asynchronous function (for example, an onclick handler). This is the perfect time for you to lazy load the module since the code will have to be fetched over the network. If mobile networks are slow, you can adopt a strategy where you prefetch the code of the modules in advance and keep them stored in the javascript heap. Only then parse and load the corresponding module on user action. One word of caution is that you should make sure your prefetching strategy doesn't impact the user's experience - for example, don't prefetch all the modules while you are fetching user data. Remember, dividing up the latency has far better for users than bunching it all together during startup.

For an HTML 5 application that takes advantage of the application cache to reduce startup latency and to serve the application offline, there are a few caveats one should be aware of. Mobile networks have decent bandwidth, but poor round trip latency, so listing each module as a separate resource in the manifest incurs quite a bit of extra startup latency when the application cache is empty. Also, if one of the module resources fails to be downloaded by the application cache (e.g. disconnected from network), additional error handling code needs to be written to handle such a case. Finally, applications today have no control when the application cache decides to download the resources in the manifest (such a feature is not defined in the current specification of the draft standard). Typically, resources are downloaded once the main page is loaded, but that's not an ideal time since that's when the application requests user data.

To work-around these caveats, we found a trick that allows you to bundle all of your modules into a single resource without having to parse any of the JavaScript. Of course, with this strategy, there is greater latency with the initial download of the single resource (since it has all your JavaScript modules), but once the resource is stored in the browser's application cache, this issue becomes much less of a factor.

To combine all modules into a single resource, we wrote each module into a separate script tag and hid the code inside a comment block (/* */). When the resource first loads, none of the code is parsed since it is commented out. To load a module, find the DOM element for the corresponding script tag, strip out the comment block, and eval() the code. If the web app supports XHTML, this trick is even more elegant as the modules can be hidden inside a CDATA tag instead of a script tag. An added bonus is the ability to lazy load your modules synchronously since there's no longer a need to fetch the modules asynchronously over the network.

On an iPhone 2.2 device, 200k of JavaScript held within a block comment adds 240ms during page load, whereas 200k of JavaScript that is parsed during page load added 2600 ms. That's more than a 10x reduction in startup latency by eliminating 200k of unneeded JavaScript during page load! Take a look at the code sample below to see how this is done.
<html>
...
<script id="lazy">
// Make sure you strip out (or replace) comment blocks in your JavaScript first.
/*
JavaScript of lazy module
*/
</script>

<script>
  function lazyLoad() {
    var lazyElement = document.getElementById('lazy');
    var lazyElementBody = lazyElement.innerHTML;
    var jsCode = stripOutCommentBlock(lazyElementBody);
    eval(jsCode);
  }
</script>

<div onclick=lazyLoad()> Lazy Load </div>
</html>
In the future, we hope that the HTML5 standard will allow more control over when the application cache should download resources in the manifest, since using comments to pass along code is not elegant but worked nicely for us. In addition, the snippets of code are not meant to be a reference implementation and one should consider many additional optimizations such as stripping white space and compiling the JavaScript to make its parsing and execution faster. To learn more about web performance, get tips and tricks to improve the speed of your web applications and to download tools, please visit http://code.google.com/speed.

Previous posts from Gmail for Mobile HTML5 Series

HTML5 and Webkit pave the way for mobile web applications
Using AppCache to launch offline - Part 1
Using AppCache to launch offline - Part 2
Using AppCache to launch offline - Part 3
A Common API for Web Storage
Suggestions for better performance
Cache pattern for offline HTML5 web application


My thoughts on the Marvel/Disney merger

I am sure that by now, you, my readers have heard about the Marvel/Disney merger, and I've kept silent about it for a few days to let things settle down, but somehow, it seems like the blogging village had a collective panic over this issue.

I don't have a vested interest in either company. I mean, I enjoy the Marvel: Ultimate Alliance games, and I love Dr. Doom, but that is the extent of my enjoyment of the Marvel properties, and I can take or leave Disney, so clearly I can be impartial in all this.

From all the griping I've been reading about this deal, there is a particular subject that I haven't seen come up as of yet (though I have to admit that I haven't been looking hard to find it either).

I am of course talking about Miramax.

You know, that company that put out so many of the movies which defined the 1990's and I am willing to wager that those bemoaning this merger have at least 3 or 4 of those Miramax films on their list of favorites.

Did Disney wreck any of those films? Did Disney make Pulp Fiction or Kill Bill into PG movies? Did Disney tell Kevin Smith he couldn't have his donkey show scene in Clerks II? Did they say that Danny Boyle couldn't make a movie about Scottish heroin addicts?

No. There was a lot of freedom for expression in the post-Disney phase of Miramax, even after the Weinsteins left.

Do you know who was doing all the cutting, slashing and various other misdeeds against films during the decade and a half that Miramax was run by the Weinsteins under Disney's financial control? The Weinsteins, not Disney... a practice they continue with at their independent company.

And the other common thread I've seen on a lot of forums is the fear that suddenly everything the two companies do together is going to be full of cross overs and such. But given the Miramax example, I think that this again will not really be an issue. Until something, I don't know, actually happens, there isn't really any reason to mess yourself over it.

Marvel is likely a much more profitable entity with a hands-off approach, and the pursuit of profits is likely a much better barometer for its relative independence than any of those conspiracy theories people are spinning.

Before you ask, yes, I would still be saying these if, say Take Two/Rockstar Games was the party Disney had acquired.

Wednesday, September 2, 2009

Midweek Video: Prinny "Where there's a Whip, There's a Way"

Disgaea's Prinnies + Ralph Bakshi's (I've been corrected... it is Rankin/Bass) The Return of the King = Pure Win



And this is just a weird video all the way around.

Heavy Duty: What Project Hosting Users are Doing

In July, the Project Hosting team announced the People sub-tab where project members can easily document their duties within their projects.


Here are the top ten most frequently selected project duties:
  1. Lead by providing a project vision and roadmap
  2. Design new features, write code and unit tests
  3. Design core libraries, write code and unit tests
  4. Have fun hacking and learn new stuff!
  5. Test the system before each release
  6. Review code changes and provide constructive feedback
  7. Plan the scope of release milestones and track progress
  8. Lead the UI design and incorporate feedback
  9. Write end-user documentation and examples
  10. Triage new issues and support requests from end-users

Those frequent duties are a testament to the serious and thoughtful software development processes often found in open source development. But, open source is not all hard work: our users also decided that it was important to document some of their more colorful duties.  Those ranged from general, "Be awesome," to vicarious, "Watch nervously as students write code," to self-effacing, "Create elaborate unit tests for small corners of the library, write hilariously malformed XML comments, and mercilessly break the build," to simply practical leadership, "Buy the pizza for everyone else."

Don't skip your duty to write your own! Just click the People sub-tab and start to document what you and your project team are supposed to be doing.

Tuesday, September 1, 2009

Oh Dear God... They Are Making a Smurfs Movie.

So now they are making a CG movie of The Smurfs.



Yeah, that's just what the world needed. And having the catch phrase on the poster be an homage to Scarface tells us all that it is going to be just for the kids, right?

Oh wait, it is being written by the crew behind Shrek 2 and being directed by the auteur behind Beverly Hills Chihuahua. So yeah, this is going to be a special movie.

Fairy Tale Economics

Ed Glaeser contemplates what fairy tales can teach children about economics. It turns out that they are not likely interested in economic nuance as opposed to what the authors likely intended.

Anyhow, if you want books where an economic message is tied in more explicitly, go no further than Anno's Magic Seeds. This book teaches the value of saving and compound interest without the need for subtlety.