FUCKING NDA

Damn, I would already be happy if they would finally accept me into the iPhone Dev program. But apart from that, full ack: The NDA sucks and is somewhat pointless.

(via fafner)

picture-2aea.png

When Amazon's S3 goes down, everything goes down the drain...

Hmm, I've used an ARM Linux distro on a Compaq (now HP) iPaq some 9 years or so ago, and I'm flabbergasted by how little the interface has evolved since then, especially the crappy keyboard.

Also, "we start going to our application, which is the + button": Wha? A + button for apps, now that's very, uhm, clear, isn't it?

OpenMoko still has a long way to go before anyone outside the FOSS community will see it as a viable alternative to the iPhone.

A video walkthrough of the QT-based frontend is also available. It isn't much better, but hey, you can playback all your OGG files (and nothing else) with it!

iPhone Web Optimization, Lesson 3: Requests and Images

So far, we've had a look at the properties of the iPhone's EDGE, GPRS or 3G link (noting that propagation delay is a worse bottleneck than bandwidth limitations, so getting the HTTP request count down is our top priority) and have talked about how to get the HTTP request count down for the textual part of a page (i.e. (X)HTML, CSS and Javascript).

By the way, in order to underline the gravity of propagation delay as a bottleneck rather than tight bandwidth, have a look at Anandtech's speed comparison of the original iPhone and the newly released iPhone 3G: Especially look at the Facebook example. Despite the 3G network having approximately 10 times the bandwidth of EDGE (at least in their testing scenario: This is network-dependent, of course), the iPhone-optimized Facebook page only loads slightly faster over 3G than EDGE. This is because bandwidth is not the bottleneck here. It's propagation delay.

Now back on topic: In this installment, we'll have a look at media data, which, in case of the iPhone, will mostly be images.

Quite often the majority of HTTP requests necessary for a page load is used to retrieve images, either being linked from your stylesheet or from image tags within your (X)HTML content. Thusly, your iPhone-optimized site can benefit greatly if you can get this request count down as much as possible.

But wait, isn't it good practice to slice up your images, serving many little pieces rather than one large image? The answer is that no, this used to be good practice back in the days when low-bandwidth internet access was the common case. Sliced images do not load faster, they just give the impression of doing so, because you see different parts of the image come up simultaneously. Over a high-bandwidth link with a moderate propagation delay, sliced images will actually load slower than the whole thing due to the request overhead. So in short: Don't do this for your iPhone content.

Let's have a look at two trivial techniques to reduce the amount of HTTP requests necessary to load your image data.

CSS Sprites
CSS sprites are an increasingly popular technique which is not only limited to iPhone-optimization, but also helps to speed up page loads on desktop computers. In short, it works by loading one big image that contains all the little image you need on various places of your page. In the stylesheet, you then use only this one image as an external reference and specify the "tile" you want to show up in a specific element by using the CSS background-position property.

So, for example, you might combine 5 10x10 pixel images into one 10x50 pixel image by stacking them vertically. You could then reference the first image by assigning the stacked image as background to a 10x10 pixel element and specifying a background-position property of 0. The second image would also be put into a 10x10 pixel element, but this time with background-position -10px, which causes the image to be "shifted up", so that the second image shows.

It's a very simple technique that can obviously help you reduce the HTTP request count a lot. I'm cutting the discussion a bit short here, since there are so many other resources on the web already. For example, css-tricks.com has a good overview of CSS sprites.

Data URLs
Data URIs (or actually URLs) are nothing more than base64-encoded binary content that is served inline within a text document, either an (X)HTML page or a stylesheet. You can use them wherever you'd usually use http URLs, e.g. in the src-attribute of an image tag, within an url() block in a stylesheet, etc. For more info, check out data URLs on Wikipedia.

Data URLs have the big advantage that you can use them to get completely rid of all external file (and image) references within your iPhone-optimized page, making it load blazingly fast, even over a slow GPRS link.

There are 4 main drawbacks, however: First, data URLs are not supported by Internet Explorer, even in version 7 (this might change with IE8), but this won't concern us much, since we're targeting the iPhone. It's only a huge reason not to use data URL in web content targeted at the desktop.

Second, data URLs are served inline, so if you reference the same image file multiple times within your document, you'll have to include it inline each time, wasting bandwidth to download the same data multiple times. However, you can easily circumvent this limitation by putting your image into a CSS class via the url() reference and then assigning this class to any element where you want the image to appear. This is good practice anyway. Thusly, this is not that much of a problem.

Third, base64-encoded data is approximately 33% larger than the same data in binary. For this reason, data URLified images should only be used for moderately sized images: If you need to display a large picture within your iPhone-optimized web content (such as a splash screen), where bandwidth becomes more of a bottleneck than propagation delay, it's better to accept the additional HTTP request and serve it as a "traditional" external image reference.

Fourth, they make developing your content slightly more inconvenient: Whenever you want to make a change to your data URLified content, you need to re-encode it and copy/paste it into your textual content again. This can quickly become rather annoying.

Therefore, I've written a little Perl script to help you alleviate this drawback. It's called dataUrlifyCss.pl and takes one required argument: The path to a CSS file. Optionally, you can pass a second argument, which will be the path to which the output is written. If you omit this second path, the script will print the results to stdout instead.

The script simply replaces all url() references within your CSS file with inline data URLs. Simply create your iPhone-optimized website with external image references in your CSS, then copy the whole filetree of the site to your disk and run the script to generate another CSS file from your original with all the external image references replaced by data URLs. You could even automate this (for example, when you deploy your content). Also, feel free to extend the script to data URLify src-attributes of image tags within an (X)HTML document too, or whatever other functionality you'd like. The basics are all there. If you're running MacOS X Leopard, you don't need to install any Perl libraries to run it (otherwise, make sure that the MIME::Base64 module is installed).

There is one more tiny issue that you'll have to deal with: Since the iPhone's processor is a lot slower than a typical desktop processor, decoding a data URL can take up to a second or so on the iPhone. Thusly, you will want to pre-decode data URLified images, especially those that need to be displayed interactively (such as on a "click" event).

To do this, simply create a div-element somewhere on your page and set the "visibility" attribute of the element's CSS style to "hidden". Do not set "display" to "none" instead, since this will cause MobileSafari to not compute the style for the element at all, preventing the decoding from happening. Alternatively, give the element a "margin-left" of "-1000px" or something, just to get it out of the way. Finally, put dummy elements with all the CSS classes that have data URLified images in them into this div-element. This will cause the iPhone to decode the data URLs for these CSS classes upon page load, so that the decoded images are already cached for when they are actually needed. If you don't do this pre-decoding, you might notice that it takes a while for an image to appear if it hasn't been used yet elsewhere in the page, and this is something you do not want.

You can see data URLs and the pre-decoding trick in action in my Quick ORF and VienNav iPhone web apps. Note that they both load with only a single HTTP request by incorporating both the data URL technique described here and the other request reduction techniques from the previous lesson. Try loading them on your iPhone over GPRS, EDGE or 3G: You'll notice that they load pretty fast even under less-than-stellar circumstances (e.g. where neither EDGE nor 3G is available, so that the iPhone falls back to the sluggish GPRS).

By combining the knowledge from these lessons, you can now build an iPhone web app that loads in a single HTTP request without introducing too much bandwidth overhead. Try it out with your own iPhone-optimized web content, and, believe me, you'll be stunned by how much faster it will load!

In the next lesson, we'll have a look at how you can test your iPhone-optimized web content under varying connection conditions such as a fast 3G link or a wonky, data-loss ridden GPRS link, all without even having to whip out your iPhone: You can do this right from the convenience of your Mac!

Previous iPhone Web Content Optimization Lessons
Lesson 1: The Thin Pipe
Lesson 2: The Dreaded Request Count

Links
CSS Sprites on css-tricks.com
Data URIs on Wikipedia
dataUrlifyCss.pl
Quick ORF
VienNav

Stunning tap dance and Shamisen performance.

There are also some other amazing, though more traditional, videos from this show on YouTube:

Shamisen vs. Shamisen
Shamisen vs. Taiko

Graph Paper

You'll find styles for wireframing user interfaces, story boarding interaction, and plotting values on a two by two grid. Plus you'll get a basic grid for drafting sitemaps or anything else that might come up.

picture-2wy9.png

Even though the transition from .Mac to MobileMe has been a disaster so far, I have to say that I really like the new iDisk icon a lot.

On one hand, the color scheme is great (well, obviously I dig the white/purple combination, it's a scheme used heavily in my own website design as well).

On the other hand, I'm intrigued by the fact that Apple is pushing the rather geeky term "The cloud" to the masses: "The cloud" originally comes from the way an internet is depicted in network diagrams (well, as a cloud), and what could be geekier than that! Still, it's somehow a nice analogy.

creative scrape

is an inspiration utility.

iPhone Web Optimization, Lesson 2: The Dreaded Request Count

In the previous post, we've had a closer look at the properties of the iPhone's GPRS, EDGE and 3G network link, coming to the conclusion that while bandwidth actually isn't so bad, propagation delay is. This means that while receiving a stream of bits is relatively quick, a transaction in the sense of "iPhone asks server for file, server sends file" is relatively expensive due to the somewhat large propagation delay. We closed with the tip to not stubbornly concentrate on getting the byte count down, but also (actually, more importantly) the count of web requests.

In this installment, I'll introduce some techniques of doing just that and to get the most out of every web request you'll have to make. Rather than providing a "copy and paste"-ready solution, we'll be focusing on concepts, not code.

In order to reduce the amount of web requests for your iPhone-optimized web content, it's important to understand its anatomy. From the perspective of individually loaded elements, we can divide a common web page into text content (made up of (X)HTML, CSS and possibly Javascript) and media content (images, sounds, etc.). Today, we'll look at how to reduce the amount of web requests related to serving text content.

Let's start with an imaginary sample web app that is supposed to be used on the iPhone. We'll call it "LibLook", a web app where you can enter the name of a book and see if it's available for renting at your local library.

LibLook consists of 3 individual pages, which are dynamically served from PHP scripts (Ruby, Perl, Python, whatever): A search form page, the search results page and an "About" page with a fancy photo of you with a party hat. Additionally, there are 2 stylesheets and one Javascript file that are imported into every page.

Now let's count the amount of web requests necessary to serve textual content for a typical usage scenario (we're intentionally omitting media data like images here, since they'll be handled in the next lession): Alice navigates to the LibLook search form (4 web requests: the form page, the 2 CSS files and the Javascript). Since she's visiting this web app for the first time, she wants to check out the "About" page now (1 web request - we assume that the CSS and Javascript files are cached). She snickers at your photo and returns to the search form (1 web request). Now she's entering the name of a book she desperately needs for a seminar and hits the "Search" button (1 web request). Sadly, the book's not available at the moment, so she locks her iPhone and lets her head hang.

In total, this amounts to 7 requests: 4 (X)HTML documents, 2 stylesheets and one Javascript (provided that caching worked). First, let's look at the (X)HTML documents.

Analyzing our documents, we see that we have 2 static pages (search form, about page) and one dynamically generated page (the search results) which are dependent on the user search terms (duh!).

Static pages are those that are "always the same", not dependent on any user input. So what we can do is serve them both at once! How do we do that? Well, with Javascript!

Rather than having two separate pages, create one new page with two top-level DIV elements. Into the first one, we'll put the search form, into the second one, we'll put the "About" page content. Rather than using hyperlinks to switch between the pages, we now use Javascript code: When the "About" link on the search form page is clicked, we simply set the search form DIV's "display" style attribute to "none" while setting the "About" DIV's one to "block". In the same way, we can switch back, too. It looks like clicking through from one page to other in a very fast way to the user, but internally, no additional data has to be transfered over the wireless link.

The popular iUI library implements this switching between DIVs together with a nice, iPhone-like "sliding to the left" type of animation, so you can just use that. Also, my VoodooPhone uses this technique to display "pages" within the bookmarklet, so you could also have a look at its source.

This way, we've already gotten rid of two web request, bringing the count down to 5 (since navigating from search form to "About" and back now doesn't need even a single additional web request).

Of course, this technique is best used if the individual pages are reasonably small, as to not load any additional large amounts of data that the user might not even navigate to (if your "About" page — that a user might only have a look at once in their whole usage history — weighs in at 1MB, you might not want to serve it together with the search form that is to be displayed every time a user visits the app). Still, however, note that a couple of kilobytes more or less won't do much of a difference, since, again, the bandwidth isn't so much adding to the "slowness" as the propagation delay is.

Before we look at the stylesheets and the Javascript file, let's talk about how the iPhone caches web content. Other than on your desktop browser, where the cache can be very large (several gigabytes), the iPhone only seems to cache content in volatile memory. This means that once MobileSafari runs out of RAM, it starts dropping older cache entries. Therefore, if the user navigates to a couple of other sites between visiting your app, it is highly likely that your stylesheets and scripts will be cache misses. Thusly, caching on the iPhone is mostly effective only during a single visit, which is a huge difference to your desktop browser, where appropriately marked files could be cached for months or even years!

Consequently, making your web app nicely cacheable isn't that important on the iPhone, so a good way to reduce the web request count dramatically is to serve both stylesheets and the Javascript inline. This is usually frowned upon for normal websites, but makes sense on the iPhone. In order to keep your app nicely organized, you can still use external stylesheets and scripts, but rather than linking to them from your (X)HTML documents, inline these files on-the-fly (server-side) by using PHP's readfile method (or your favorite language's equivalent). Such a trivial optimization, but now our request count is already down to 2, shaving another 3 requests off due to the inlining. Awesome!

We've introduced one inefficiency now, though: Since the scripts and stylesheets are no longer externally linked (and thusly cached within the same session), we have to include them inline on both the search form/about page and the dynamically generated search results page. That's a waste of bandwidth!

AJAX to the rescue! As the final optimization, we change the "search results" script from creating its own independent page to creating just a new DIV (or whatever other block element is appropriate) and adding it to the search form page's DOM dynamically via Javascript (for example, using the innerHTML JS property). With this technique, we don't need to serve the inlined scripts and stylesheets again since the user basically stays on the same page now during their whole visit, even if they conduct multiple searches: Not only do we load the scripts and stylesheets only once, but the user can now go back to the search form to do another search without another page load, since we can just re-display the form using, again, Javascript, the same way we switch between the "About" and "search form" page. Pretty neat, ain't it?

iUI already comes with Javascript methods to load subpages AJAX-style, so you can use that. Additionally, it's very easy to roll your own, light-weight AJAX page loader, so this shouldn't be holding you back either.

To sum it up, we've now reduced our web request count for the sample scenario from a hefty 7 to just 2, all without adding a single additional byte in total! If you'd compare the perceived "speediness" of the old and new versions over 3G, EDGE or even GPRS, you'll notice that the optimized version will feel dramatically faster.

Looking back, this is what we did in a slimmed-down list:

  • Serving static pages together, switching with Javascript.
  • Inlining scripts and stylesheets
  • Using AJAX, so that the user stays on the same page.

A couple of thoughts before finishing this post: Not all of these techniques might be applicable to your app, depending on its usage structure and complexity. Still, the overall ides should be helpful.

Also, what about the 5 iPhone users that have switched off Javascript in MobileSafari? Since all 3 techniques rely on Javascript (apart from the inlining), you'd have to either ignore these users or check for Javascript and fall back to an unoptimized version if it's off. Note, though, that inlining stylesheets might still be applicable, if the sheets are sufficiently small (only a couple of kilobytes). This is because bandwidth isn't so much of an issue as propagation delay, so the bandwidth-penalty of inline-loading the sheets on multiple pages might be worth it.

You can see all of the 3 techniques in action in my Quick ORF and VienNav apps, both of which are built on top of iUI: The "About" page is already included in the index page, the scripts and stylesheets are inlined and the requests are loaded via AJAX. Both apps use the absolute minimum amount of web requests, making them feel pretty fast even when loading them over GPRS.

Of course, there are many more techniques to provide for more perceived page loading speed, some of them not limited to iPhone apps. Yahoo's performance tips](http://developer.yahoo.com/performance/) are an awesome resource on this topic. Additionally, here are some ideas that might be worth thinking about, too:

  • Predictively prefetching data via AJAX
  • Serving zlib-compressed pages
  • Packing/minifying your Javascripts and stylesheets
  • Using higher JPG compression
  • Using JPG for photos, but PNG for icons
  • Getting rid of unnecessary (X)HTML markup (by using CSS better)
  • Putting Javascripts at the bottom of the page
  • Doing more work client-side with Javascript, such as form validation.
  • Using shorter CSS class names and DOM element IDs (they can sum up!)

In the next installment, we'll talk about how to reduce the web request count for your media files (mostly image files in case of the iPhone).

UPDATE: Next lesson now online

Previous iPhone Web Content Optimization Lessons
Lesson 1: The Thin Pipe

Links
iUI
PHP 'readfile' function
Quick ORF
VienNav
VoodooPhone

squirrel.jpg

I was visiting my parents today. They've been keeping a bowl of sunflower seeds for birds and squirrels on their balcony for a while, so while I was sitting on the doorstep to their balcony, this squirrel suddenly jumped off a tree and landed right in front of me. Apparently, it was not afraid of humans anymore at all. It was even posing for me when I snapped a picture with my iPhone.

I like squirrels.

FAIL Blog: Pictures and Videos of Owned, Pwnd and Fail Moments

I have an insanely good time browsing this blog, no matter (or just maybe because of) how primitive some of the entries are!

iPhone Web Optimization, Lesson 1: The Thin Pipe

With the global iPhone 3G launch less than a week away, iPhone-optimized web content might become even more important than it already is, especially if the assumption that iPhone users make up for the largest chunk of mobile surfing holds internationally as well.

While there are lots of great resources about how to design web content for the iPhone and MobileSafari's unique capabilities, information about how to optimize content is scarce. For this reason I decided to write a couple of posts about the topic.

As a first step, it is important to understand in which ways the iPhone is different from other web browsing platforms. At a glance, we see that its screen is comparatively small and that it has multitouch browsing capabilities that are unique to it at the moment. However, harnessing this knowledge falls into the field of "design", not "optimization". Obviously, successful iPhone web content must be formatted to fit the screen nicely and must be usable with multitouch (i.e. no fancy javascript drag&drop coolness, etc.).

From the perspective of content optimization, it's more interesting to take a look at some technological properties: The iPhone's performance in processing web content for display and the way it accesses the internet, namely wireless LAN and GPRS/EDGE.

The rendering performance will only take a secondary priority here, since most of its limitations are already overcome implicitly by designing for the small screen, which means that we have to keep websites simple enough. Websites whose loading times are bound by rendering performance issues on the iPhone are usually those that are heavily overloaded and clearly not designed for a mobile browsing experience anyway.

Therefore, let's take a closer look at the networking hardware now: Since we're optimizing, we gain most by embracing the worst case. If the worst case scenario works fine, all the others will work fine too.

The Thin Pipe
"But EDGE and GPRS are just slow, so if we keep everything small, the site will load fast. And once the iPhone 3G comes out, this won't be an issue anymore at all!", you might think. Well, is it true? And what exactly do you mean by "slow"?

The thing is that there are actually multiple dimensions of "network speed", the three most important to us being "bandwidth", "propagation delay" and "packet loss".

Bandwidth refers to the overall amount of data that can be pushed through the pipe within a given period of time. For EDGE networks, this is 230-something kbps, with around 100 kbps being the average case. Plain GPRS bandwidths are an order of magnitude smaller than that, typical 3G/HSDPA bandwidths are an order of magnitude larger. Note that these are not insanely small measures or anything (a couple of years ago, having GPRS bandwidths over wired telephone lines was considered to be normal!). Therefore, bandwidth only plays only a limited, though important, role in making mobile surfing feel "slow".

Propagation delay is the important property that is often overlooked. It refers to the amount of time that passes between the signal being transmitted from one endpoint and it being received at the other one. Note that this is not referring to theoretical physical limits (like the speed of light), but to plain simple technical limits such as wait times due to timesharing protocols, time spent processing at the endpoints, etc. Wireless networks such as GPRS, EDGE and even 3G/HSDPA have very large propagation delays when compared to wired links such as ADSL lines. This has to do with the way data is being sent over the air (I don't want to go into detail here since it's not really important for our purposes, but it has to do with the timesharing necessary so that multiple clients can be connected to the same cell, as well as the modulation algorithms).

Typically, GPRS links have propagation delays of about 500ms (often much more), EDGE falls somewhere between 200ms and 500ms, and 3G can theoretically be much faster, but often also exhibits delays above 100ms. By comparison, the propagation delay of an ADSL link between your home network and your ISP's router is usually only a couple of milliseconds!

Note that propagation delay and bandwidth are independent properties. For example, there are some links that have insanely large bandwidths, but also huge propagation delays: Satellite links! Similarly, a link can have a rather meager bandwidth while having a fast propagation delay, such as ISDN links. In any case, the two properties do not influence each other.

The last property, packet loss, refers to the amount of (random) data packets being lost during flight. This has to do with link quality and is often not even noticeable for wired links. For cellular networks, however, we have to keep the possibility of a large packet loss ratio in mind that can be caused by bad reception.

The Real World
Now let's look at the interaction of these properties in a real-world theoretical example (heh!): Let user A download 100KB of web content from server B, say, an image file. A uses her iPhone over an EDGE connection with good reception and a bandwidth of 100 kbps. It takes 250ms for the request sent by her iPhone to reach the first router (the propagation delay) and 250ms again for the reply to be sent back from the last router to her iPhone. The rest of the packet flight time (within the internet) takes about 100ms, whereas server B needs about 50ms to actually dispatch the request and start serving the file. Summing up all these delays (propagation delays and the server's processing time), we see that user A will only receive the first bit of data (and start to see something "appearing" in her MobileSafari window) after 250+100+50+100+250 = 750ms. Then it will take 8-10 seconds for the 100 kilobyte file to be downloaded over the 100 kilobit/s EDGE connection (8 seconds minimum, but it might take longer due to packet loss).

In this scenario, the largest chunk of time (8-10 seconds) is taken up by the file actually downloading. To contrast this, though, assume user A now downloads a tiny 1 kilobyte file, say, a snippet of text, from the same server over the same connection. Pushing 1 kilobyte over a 100 kilobit/s link takes only 80ms (packet loss not factored in), but the waiting time caused by the various delays, especially EDGE's slow propagation delay, remains constant: Still 750ms! So in this case, the majority of time is actually spent waiting rather than downloading!

This might come as a surprise to those who equate perceived network speed with bandwidth, but as we have seen, sheer content size (and consequently EDGE/3G bandwidth) might not even be the most limiting factor in an iPhone-optimized website. It might be the slow propagation delay. Even worse, 3G, while being considerably better than EDGE in this departement, also has a large propagation delay compared to wired links.

Seeing that the bandwidth (especially if EDGE or 3G is available) isn't even that bad, but propagation delay is (or can be), we can rephrase the intuitive conclusion of "having to keep everything small" to something along the lines of

  1. Minimize the amount of individual web requests
  2. If 1. is satisfied, minimize the byte count of your content

Thusly, there are, surprisingly, many many scenarios in iPhone web content optimization where serving a slightly larger amount of data with fewre individual requests is preferable over serving less data, but via more requests!

Conclusion
Now that we have a better understanding of why surfing over cellular networks feels slower than over wired links, my next post on this subject will introduce some useful techniques to minimize the amount of web requests in your iPhone-optimized web application or site.

UPDATE: Next lesson now online

Links
3G on Wikipedia
GPRS on Wikipedia
EDGE on Wikipedia

Chyrp Ping-o-matic module for 2.0b3

I just thought I'd mention that I uploaded a new version of my Chyrp Ping-o-matic module to the official "Extend" section. If you want to automatically ping pingomatic.com (and/or similar services) when you publish a post on your Chyrp 2.0b3 blog, you can grab the new version here.

Be aware that I'll have to update it again when 2.0 comes out (but I will announce this here when it becomes relevant). Also, the "original" version for Chyrp 1.1.3.x is still available as well.

Ping-o-matic module for Chyrp 2.0b3
Ping-o-matic module for Chyrp 1.1.3.x

applestockscandal.jpg

Dear Apple,

I find it very cute how you selectively zoom into your stock's chart in your "iPhone 3G Guided Tour" video, so that we can only see your valuation rally dramatically.

Don't forget, though, that reality looks a bit dimmer (unless you bought in February, yay!).

Due to recent irregularities involving, ahem, certain derivatives of your stock, I'd suggest being a bit more careful with incidents like this, especially since many of your customers are also stockholders familiar with your company's valuation.

:-)

VienNav: Now available in Dutch too!

I just added a Dutch localization to VienNav. Many thanks to Rainer Scheichelbauer for taking the time to provide the translation!

Link: http://gkaindl.com/iphone/viennav