Thursday, October 02, 2008

Dojo 1.2 Loader and Build System

Dojo 1.2 is now available! Check out the release notes for more detailed information.

I attended the Dojo Developer Day in Boston on Sunday 9/28 and the Dojo Community Day at the Ajax Experience conference on Monday 9/29. It was really nice of the Ajax Experience folks to set up community time for the JavaScript toolkits.

During the Community Day, I gave a short presentation on some new things in Dojo 1.2 with the Dojo loader and the build system. I tried using the Google Docs presentation thing. You can see the slides here (some notes are after the slides):



customBase build option
The final example in the slides demonstrates how you can create a 5.5 KB (gzipped) dojo.js file and dynamically load it after the page loads, so if your site uses progressive enhancement, your up-front Dojo cost can be zero bytes, and just load as little as possible for the functionality that you use.

The 5.5 KB dojo.js file is possible using the "customBase" property of the dojo.js layer in a build profile. Normally we encourage you not to tamper with the contents of dojo.js (what is referred to as Dojo Base), but the customBase build option can give you more control on what parts of Dojo Base you want to load. With the customBase option, the build will go through all the JS files and automatically add dojo.require() calls for the necessary dojo._base modules.

Only use customBase if you keep all your JS code in JS modules -- good practice anyway, and keeps with progressive enhancement suggestions. Do not use customBase if you have Dojo calls inside HTML source.

Using customBase on the "dojo.js" layer with no dojo._base modules (just the loader and some bootstrap functions), the non-gzipped size of  dojo.js comes out to be 13KB (recall from above it is 5.5 KB gzipped). So it is small enough to fit under the 25KB non-gzipped size limit that the iPhone/iPod touch use to allowing caching.

You will likely need to use more of Dojo Base than what is in the 13KB non-gzipped file, but you can tune that by creating more layers and playing with the build to so that all layers are under 25KB.

djConfig.addOnLoad
Another option for use with progressively enhanced web sites, or when you want to load Dojo after page load: djConfig.addOnLoad allows you to set a function to run after Dojo loads. It is most useful when used in conjunction with djConfig.afterOnLoad (used when you manually load Dojo after page load).

Here is a complete example showing djConfig.addOnLoad, djConfig.afterOnLoad and djConfig.require.

There is a bug about using djConfig.require in conjunction with a dojo.js generated via a customBase build, so only use djConfig.require when using a complete Dojo Base file.

Thanks go to Matthew Russell for suggesting djConfig.addOnLoad for the 1.2 release.

stripConsole
There is a new build option for stripping out console method calls. stripConsole=normal strips out all console.* calls except console.error and console.warn. stripConsole=all strips all console.* calls.

Safari 3.1 sometimes has an issue with console.debug not getting defined (fixed in webkit trunk), so this build option can help avoid that issue until Safari is fixed.

Saturday, June 14, 2008

Mobile Development

I was recently asked about my experiences making TinyBuddy IM. Here are my very biased thoughts about it and mobile development in general.

My Background
I like to make web products that people use. I am a front-end developer, and I love using JavaScript, HTML and CSS. I have done some C/C++ for a cross-browser streaming audio browser plugin. I recently played with Objective C as part of an iPhone SDK experiment. I did Java on the server for a few years too.

HTML, or some sort of declarative markup, is the way to code front end UI. It clearly shows the nested relationships between components. However, I liked the Interface Builder approach in the iPhone SDK, very WYSIWYG. It still some kinks to work out with the beta iPhone SDK though.

I also like trying to reach the largest possible audience with the shortest toolchain. To me, this means favoring an HTML/CSS/JavaScript UI first, and only considering other alternatives when that approach will not work. Particularly since I favor developing applications for the internet.

One Mobile Renderer to Rule Them All
I did not do mobile development until TinyBuddy IM. It just seemed too painful -- too many custom environments, too many cumbersome toolchains for native apps. And the browsers really sucked.

However, now with WebKit on the iPhone and in Android, it is tolerable. Those platforms also have a decent toolchain for "native" apps: iPhone SDK/Objective C for iPhone, and a Java environment for Android.

However, WebKit is most interesting to me: it is a modern, very capable browser that will be on two major mobile platforms. While JavaScript performance is still slow on mobile browsers (both compared to desktop browsers and native code), there is promise that it will get faster with WebKit's SquirrelFish.

For the first time, it is actually possible to consider making a powerful web app for a mobile device. You have good odds of developing one mobile app that runs on multiple devices too. Or at least have lots of code overlap.

Of course a web app is not appropriate for every app, and it does not have access to as many services as a native app, but it does have a lot. With the latest WebKit for instance, you will have local storage.

You Are Dead to Me
Not every mobile device has WebKit. What about Windows Mobile devices, BlackBerry, or all the other devices out there in the market today? Well, for me, they do not make it easy to develop. And I am lazy. I use an iPhone, so I am going to develop for what I use. However, I chose an iPhone specifically because it is easy to do development.

So the other platforms are not that important to me, and if my developer laziness is any indication, they are in for some trouble. They need to get WebKit or Gecko on their devices and use a better toolchain. Opera's browser may be an option too, but I am not clear if it is up to the capabilities of WebKit. If it is, great. I like the Opera on the Wii.

Again, it may not be reasonable to discard these other platforms, depending on your app, but I have decided the other platforms are not worth the effort, given my interests. I really want to make interesting end user products without spending time on platform minutia, and I feel like the iPhone's and Android's reach will be good enough for me.

Mobile Application Design
I approach the technical design of a mobile app by trying to see if the following approaches fit the problem:
  1. A purely browser-based web app.
  2. A native app that gives a "desktop" icon, and access to phone services (for instance, location services), but use a WebKit view for the main UI interface. Set up hooks in the WebKit view so it has access to the phone services.
  3. A purely native application.
#2 has many shades to it, but I like it because it minimizes installed code. Revving a native application is more work than a server-based one.

Remember, I'm assuming this is an internet app, and you know the HTML/CSS/JavaScript trifecta already.

There are tradeoffs. Speed of loading/dependence on network, but again, I prefer to first look at a web-based solution first: maybe it makes sense for the native app to cache the HTML/JS/CSS/images locally.

Native Apps
What you want to build may not work as a web app. For those cases I still prefer iPhone or Android.

For iPhone, you have a nice dev environment with a WYSIWYG UI tool (Interface Builder). Objective C feels a lot like JavaScript to me -- some concept of a prototypical object, and runtime, dynamic dispatch where you can send messages to objects that may or may not respond to that type of message. Unfortunately you have to do the memory retain/release thing, but it is manageable. Lots of helpful videos and examples at the iPhone Developer site too.

For Android, using Java syntax and libraries are a big plus over some sort of C/C++ thing. Java can be verbose, but it is easy to program with an IDE, and hopefully they kept in the garbage collection like Java. That alone is a big win. I have not used Android yet, and I have heard of problems with trying to program in that environment (maybe they have been worked out now?), but it seems worth spending effort on that path. It seems like it has a good shot of survival over the long run.

UI Design
There is a great intro video on the iPhone Developer site about "User Interface Design for iPhone Applications". You will need a (free) Apple Developer ID to view it. But take the time to view it.

The main point: a mobile app is not a desktop app. Do not try to do too much. For TinyBuddy IM, I decided to not include buddy list management features in the UI (add/remove/move buddy). The app was designed for doing quick IMs with your buddies. Buddy list management just seemed to get in the way of that goal. Not to mention the lack of copy and paste on the phone. It just did not seem like a worthwhile activity for a mobile app.

Also, use the UI paradigms available on the phone. For native apps, Apple has a lot of built in templates for using the standard lists and tables you see throughout the iPhone UI. I used a very early version of iUI for a web toolkit that gives an approximation of the native iPhone UI. There may even be some resources in the latest iPhone SDK to make web development easier in this respect.

So, keep it simple, keep it familiar. Once you get the fundamentals down and released something, you can consider your own style (if appropriate).

Pain Points
It is not all roses. There are notable restrictions making mobile web apps. These limitations are specifically from the iPhone, but I would expect them to be roughly the same if not more oppressive in Android environments.
  • Resource limits.
  • Cache limitations (25KB max size, uncompressed, if you want it cached, 19 total cacheable items).
  • As mentioned above, JavaScript performs slower than desktop JavaScript or native code.
  • You web app is paused when it is not in the forefront (also a limit for native apps, but native apps will have a notification service you can use that will help with this).
That last one is particularly vexing for TinyBuddy IM, since it is an IM client. So a native app for the IM problem space is probably more appropriate. Or some sort of native component that ties into to the notification service? :)

TinyBuddy IM Weaknesses
I need to spend more time optimizing the TinyBuddy IM code:
  • I do not do any sort of "Fetch next 25" sort of thing to keep the buddy list size down.
  • The wiping between screens is slow.
  • The IM conversation window needs more polish.
  • Maybe some better navigation for multiple IM conversations.
So I definitely did not get it right with TinyBuddy IM. Now that there is a native IM app under development, I probably will not rev TinyBuddy IM again. However, I am amazed TinyBuddy IM works as well as it does -- I was able to be a little bit lazy, and still get something somewhat useful out. A good indicator for that platform.

Authentication
Most things I want to build require user authentication for at least some part of it. For TinyBuddy IM, that meant using AOL's OpenAuth authentication, since the Web AIM API used it. OpenAuth has a browser-based authentication system that any web page can use, and it even supports consuming some validated OpenID providers.

OpenAuth has a "clientLogin" API for desktop clients and Flash/AIR apps but I do not prefer it since it basically means the user hands over their name and password to your app, and then your app sends it to OpenAuth. While that might be nice from a usability standpoint, it bothers me personally from a security standpoint.

This is where something like OpenAuth's browser API (and in general OpenID in the browser) provides better protection. You only enter your name/password on the identity provider's web site, and a token is passed back to the web app that requires your credentials.

As an end user of this system, I can verify by the browser URL who is asking for my name/password. As a developer, I like just not having to touch passwords at all. It absolves me from the security issues with trying to manage passwords, even if it seems like I am only passing the password through to OpenAuth's clientLogin.

However, most end users are not this particular about using applications, they are happy to give their password to any site asking for it, particularly if it seems to be done in goodwill. They just want to use the app. Also, the browser based authentication can be weird -- popping a new window to get the auth credentials.

But the OpenID approach is the way of the future (going to another site to authenticate), so might as well get used to it. Particularly now that the OpenAuth authentication page has a "Remember Me" option, so the user does not have to keep entering name/password on every visit.

Have Fun!
Enough of my ramblings. The big thing for me: mobile development can be fun, particularly with the iPhone platform. Android, while not at the same level as iPhone development yet, also seems like it has promise too.

Friday, March 28, 2008

The Beauty of Dojo 1.1

The Dojo JavaScript Toolkit version 1.1 is available:
There are lots of goodies in this release (see the release notes for full details), but here are some of the new features that resonate with me. I am primarily a Dojo Core user, not much Dijit or Dojox. For other perspectives on the new features, see the 1.1 blog announcement, and Shane O'Sullivan's blog post.

Multiversion Support
One of the slicker features (IMO, since I added it) is multiversion support: you can now run Dojo 1.1 with other versions of Dojo in the page without conflicting. You can also choose to rename dojo, dijit and dojox to other names. As proof:
The multiversion support is great if you want to provide your own JS library, but use Dojo underneath. What is even cooler: multiversion support works from the CDN (see the source for the examples above)! So if you are thinking of migrating from an older Dojo version, you can experiment with Dojo 1.1 in a new namespace without having to download 1.1.

Load Dojo after page load
Dojo 1.1 can can be loaded after page load (after the window.onload event fires) by setting djConfig.afterOnLoad to true. This makes the initial render cost for using Dojo near zero, and it plays nice if you want to do extreme progressive enhancement. Use the new djConfig option in conjunction with djConfig.require, to load dojo along with the modules you needed dojo.required after dojo loads. See the the demo page for an example.

Adobe AIR support
Dojo now provides strong support for AIR in addition to Dojo's existing integration with Google Gears via dojox.offline.

Client-side data storage via dojox.storage
If you want client side data storage, dojox.storage gives you a few options, and auto-detects the best one. dojox.storage has been updated to allow for using Dojo Gears, HTML 5 DOM storage, Flash or AIR DB storage.

Build system CSS optimizations
The build system will now inline @import calls that are in .css files in addition to stripping comments and whitespace in .css files. See the New Build Options section.

Try it out!
If you would like to try Dojo, but are not sure how to start, you can always start small: If you just use Dojo Base (one file, dojo.xd.js, from the CDN), you get a solid JavaScript base that makes building progressively enhanced sites much more enjoyable. A rough run-down of the Dojo Base functionality can be found here. That article is for Dojo 0.9, but it still applies for 1.1. Dojo 1.1 is slightly larger than the numbers quoted for 0.9: The 1.1 dojo.xd.js is 29KB gzipped. See the 1.1 release notes for the new features that account for the size increase.

I prefer to stick with Dojo Base, with some additions from the Core modules (like dojo.io.script, which allows using JSONP APIs, like the ones provided by Web AIM). This is how I approached development for the AIM Chat web site and for the iPhone IM web app TinyBuddy IM. But given Dojo's depth, I was able to leverage the Dijit widgets to create a simple admin site for AIM Chat by adding in a few more dojo.require calls. Sweet!

I am really amazed at the amount of work that has gone into Dojo 1.1. The more I use it, the more I feel it is the complete JavaScript toolkit solution. You can do the small, quick progressively enhanced web sites using just Dojo Base from the AOL CDN, but scale all the way up to very rich experiences that use the full power of widgets, awesome data stores, offline storage, and incredible 2-D drawing capabilities (with charting!).

I feel the Dojo community is really hitting their stride now. Great job everyone!

Thursday, January 31, 2008

Browser and Dojo updates on Fragment ID messaging

Some browsers have changed how they deal with fragment ID messaging:

Safari 3 throws an error if a child frame tries to change a parent frame's location, but only if the parent frame is not the top-most frame. So, this test works, but this one fails. Parent frames are allowed to change a child frame's location.

Opera 9.25 has locked down cross-frame access to some frame properties. As Julien LeComte pointed out, Opera supports the HTML5 cross-document messaging API, so that is a viable alternative.

I have updated dojo.io.proxy so that it now works in these browsers: IE 6 and 7, Firefox 2 and 3beta2, Safari 3 and Opera 9.25. You can get it from the Dojo development trunk, or wait for Dojo 1.1. The new dojo.io.proxy code works with Dojo 1.0, and there are no API or usage changes.

This new code also improves the IE7 codepath: before the code used to use 3 frames to do the transport, but now it only uses 2 frames, like the rest of the browsers. I was not being very smart about the ordering of the frames in the old code.

Thanks go to Julien LeComte for pointing out the Opera cross-document API and for diagramming another way to do fragment ID messaging.

dojo.io.proxy differs from Julien's CrossFrame approach:
  • it allows very large messaging (it supports fragment ID chunking)
  • it is focused on providing a data transport -- it provides an XMLHttpRequest facade. It is not a communication transport for UI widgets.
Julien did not want to use location polling, since it increases CPU usage. dojo.io.proxy does use polling to do the communication (this allows for chunking to support large messages), but polling is active only while the message is in transport. I consider the window.location polling less resource-intensive than doing a DOM animation. CPU usage could be tuned by slightly extending polling interval if it is a concern.

dojo.io.proxy creates the frames only when the request starts, then it destroys the frames when the response finishes. This preserves the history stack in all browsers except Opera.

There is a very primitive test page if you want to see the latest code in action.

Wednesday, January 30, 2008

David Baron's solution for X-UA-Compatible

I like David Baron's alternative to X-UA-Compatible: if the main problem is intranets, give intranet folks a way to configure IE to use the old rendering mode just for their hosts.

I'm interested if this would be enough for Microsoft. If they claim it does not cover all the cases, it would be good to get some sort of metric/percentage of how much it would cover. Seems like it would cover the vast majority case. Probably close to 100% of the cases where Microsoft's revenue is impacted.

If the claim is that they cannot "break the web" even for that small case on the internet where their revenue is not directly impacted, I wonder how important those sites are anyway. I expect there are lots of sites that were made with older browsers in mind, but the site is probably abandoned too. As long as you can sort of read the content on the page, maintaining precise layout is probably not important.

If Microsoft is still set on using a flag/switch in HTML/HTTP header, I still prefer a cultural flag and not a product version flag.

Saturday, January 26, 2008

Using Aptana Jaxer for search engine friendly pages?

I am interested in Aptana's Jaxer because they seemed to have gotten Gecko to work on the server. From what I have read before, the tricky part is getting Gecko to run without the need for a windowing service (like X-Windows). Maybe Jaxer still needs a windowing service, I have not looked that closely.

I am not so interested in using their runat="server" or server-proxy capabilities, but more interested in getting Jaxer to render my page to the final "onloaded" DOM that could then be sent to a search engine.

However, I have not seen an option yet to tell it "treat the whole page as runat server" or something like that.

Here is what I want to do (condensed from my previous post on searchable ajax):
  • Do the model/view/controller in HTML/CSS/JS. I normally want this all to run in the user's browser.
  • However, for search engine requests, I want to do some Apache rewrite/proxying to a server-side Gecko that would render the DOM as it would look after window.onload, then serialize that DOM as the result of the search engine's request.
I wonder if Jaxer could be used for the "server-side Gecko" part. If so, that would be sweet. That would allow my web app to be indexed by search engines properly, but still give me the development model I want. No special dev work to get search engine benefits.

Wednesday, January 23, 2008

X-Web-Epoch instead of X-UA-Compatible

This is in response to the X-UA-Compatible proposal from Microsoft to help IE8 and future IE browsers to know how to render web pages. There is a lot of commentary on the subject, but here are what I believe to be the original (public) sources for the proposal:
I understand and sympathize with IE's position: they need a switch to know when they can use a more standards-compliant rendering engine. There is a vast sea of font tags, tables, spacer images and document.all references inside corporate intranets, and no one is going to update that code, ever. However, any new versions of IE are expected to be able to render that sea of forgotten markup faithful to the original coder's intent. A responsibility IE gets for winning the first round of browser wars.

However, IE is getting push from today's web developers that want something easier to code against given today's suggested cultural approach to web development, namely adherence to publicly accepted web standards.

X-UA-Compatible provides a switch for IE to know what the developer wants: does the developer want the old wild west behavior, or a more standards-based behavior?

However, I do not like the X-UA-Compatible proposal because it focuses too much on specifying a rendering engine and engine version (like specifying IE=8). Actually it is even more specific than rendering engine, it is really a product version switch.

I think the switch should be more of a "culture version" switch than an explicit product version switch. Tying the switch to product versioning seems too fragile. Ideally, IE8 and IE9 will be released before there is a cultural shift in expectations over development.

It also makes it hard for me as a more standards-based developer to make a decision on X-UA-Compatible. I'll likely just use the "edge" value, but then over time, "edge" will lose its meaning and it will just mean "what web developers do today". We'll need a new switch in the future once "edge" reaches the status of today's DOCTYPE.

Maybe it makes more sense to use a culture version number instead. For the sake of argument, I'll call it X-Web-Epoch, but I am not tied to that name. The value for X-Web-Epoch would be an URL that corresponds to the epoch that is targeted. I see having two epochs right now:
  • Epoch 1: The tag soup, wild west version of the web IE is expected to render, in particular inside corporate intranets.
  • Epoch 2: The standards-based development of today. I would also include "the expectation that things develop and change over time" as part of that Epoch 2.
Epoch 1 is the default. It is used for web pages that do not have a X-Web-Epoch META tag or HTTP header.

So, something like this for Epoch 2:

<meta equiv="X-Web-Epoch" content="http://www.w3.org/epochs/2">

That www.w3.org URL does not actually exist, so spare the w3.org servers and do not try to actually go to it. This does not have to be the actual URL mentioned above, just some URL.

The URL should be resolvable to a real document that explains the cultural assumptions of that epoch.

The Epoch 2 document could list things like:
  • Assumes public standards-based development.
  • List the general set of standards.
  • Maybe list things like progressive enhancement, how to design for accessibility.
  • Most importantly: things will change over time as bugs are fixed to improve standards compliance. There also may be new standards adopted.
  • It could have a changelog since this document is allowed to change slightly over time.
The document would hopefully set expectations accordingly, in particular that things may change slightly over time. Bonus points: the document can serve as a pointer to how best to code in that Epoch.

Ideally the definition of Epoch 2 is big enough that we might have a chance to go many browser versions without needing a new Epoch, and browsers can go a long time without needing completely new rendering engines.

In reality, cultural expectations will change over time, and we will likely need an Epoch 3 to allow the browser market leader of that time to be able to implement a new rendering engine, so they do not have spaghetti code in just one giant backwards-compatible engine. But again, there should be a longer time span vs. what might be expected with X-UA-Compatible.

It also seems like a better approach than using "edge" in X-UA-Compatible.

This would give IE the switch it needs for its new rendering engine. Other browsers of today, they are just fine moving along with what they have now. They can ignore the switch for now, until they become market leader and have to adapt to an Epoch 3. Hopefully, web developers get iteration from IE in a more timely manner, and a better baseline for development.