<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>David Calhoun&#039;s Blog &#187; mobile</title>
	<atom:link href="http://davidbcalhoun.com/category/mobile/feed" rel="self" type="application/rss+xml" />
	<link>http://davidbcalhoun.com</link>
	<description>Just another blog</description>
	<lastBuildDate>Mon, 07 May 2012 02:06:20 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<item>
		<title>iPhone 4S, iPhone 4, and iPhone 3GS photo comparison</title>
		<link>http://davidbcalhoun.com/2011/iphone-4s-iphone-4-and-iphone-3gs-photo-comparison</link>
		<comments>http://davidbcalhoun.com/2011/iphone-4s-iphone-4-and-iphone-3gs-photo-comparison#comments</comments>
		<pubDate>Fri, 14 Oct 2011 23:28:24 +0000</pubDate>
		<dc:creator>David</dc:creator>
				<category><![CDATA[mobile]]></category>

		<guid isPermaLink="false">http://davidbcalhoun.com/?p=823</guid>
		<description><![CDATA[More photos likely to come.. this is just after I unboxed my new 4S. Time to play with it a bit! iPhone 4S iPhone 4 iPhone 3GS iPhone 3GS (alternate white balance point)]]></description>
			<content:encoded><![CDATA[<p>More photos likely to come.. this is just after I unboxed my new 4S.  Time to play with it a bit!</p>
<h3>iPhone 4S</h3>
<p><a href="http://davidbcalhoun.com/wp-content/uploads/2011/10/4S.jpg"><img src="http://davidbcalhoun.com/wp-content/uploads/2011/10/4S-1024x768.jpg" alt="Canon 7D, shot with an iPhone 4S" title="Canon 7D, shot with an iPhone 4S" width="1024" height="768" class="aligncenter size-large wp-image-824" /></a></p>
<h3>iPhone 4</h3>
<p><a href="http://davidbcalhoun.com/wp-content/uploads/2011/10/4.jpg"><img src="http://davidbcalhoun.com/wp-content/uploads/2011/10/4-1024x764.jpg" alt="Canon 7D, shot with an iPhone 4" title="Canon 7D, shot with an iPhone 4" width="1024" height="764" class="aligncenter size-large wp-image-825" /></a></p>
<h3>iPhone 3GS</h3>
<p><a href="http://davidbcalhoun.com/wp-content/uploads/2011/10/3GS.jpg"><img src="http://davidbcalhoun.com/wp-content/uploads/2011/10/3GS-1024x768.jpg" alt="Canon 7D, shot with an iPhone 3GS" title="Canon 7D, shot with an iPhone 3GS" width="1024" height="768" class="aligncenter size-large wp-image-826" /></a></p>
<h3>iPhone 3GS (alternate white balance point)</h3>
<p><a href="http://davidbcalhoun.com/wp-content/uploads/2011/10/3GS-alt.jpg"><img src="http://davidbcalhoun.com/wp-content/uploads/2011/10/3GS-alt-1024x768.jpg" alt="Canon 7D, shot with an iPhone 3GS" title="Canon 7D, shot with an iPhone 3GS" width="1024" height="768" class="aligncenter size-large wp-image-827" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://davidbcalhoun.com/2011/iphone-4s-iphone-4-and-iphone-3gs-photo-comparison/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Mobile Performance Manifesto</title>
		<link>http://davidbcalhoun.com/2011/mobile-performance-manifesto</link>
		<comments>http://davidbcalhoun.com/2011/mobile-performance-manifesto#comments</comments>
		<pubDate>Tue, 11 Oct 2011 07:44:45 +0000</pubDate>
		<dc:creator>David</dc:creator>
				<category><![CDATA[mobile]]></category>
		<category><![CDATA[performance]]></category>

		<guid isPermaLink="false">http://davidbcalhoun.com/?p=768</guid>
		<description><![CDATA[Earlier this year I gave a talk (slides) outlining the latest and greatest in mobile performance, including a bit of my own unscientific research into carrier latency and bandwidth thanks to boomerang.js. I realized that interest in mobile performance has exploded recently, especially with Steve Souders announcing his focus on mobile, and I thought it [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://davidbcalhoun.com/wp-content/uploads/2011/10/odometer.jpg" alt="" title="Dashboard with odometer" width="800" height="299" class="aligncenter size-full wp-image-806" /></p>
<p>Earlier this year I gave a <a href="http://www.meetup.com/SF-Web-Performance-Group/events/16116764">talk</a> (<a href="http://davidbcalhoun.com/present/mobile-performance/">slides</a>) outlining the latest and greatest in mobile performance, including a bit of my own unscientific research into carrier latency and bandwidth thanks to <a href="https://github.com/yahoo/boomerang">boomerang.js</a>.</p>
<p>I realized that interest in mobile performance has exploded recently, especially with <a href="http://www.stevesouders.com/blog/2011/01/10/announcing-my-focus-on-mobile/">Steve Souders announcing his focus on mobile</a>, and I thought it was time for an update, this time in blog form.  Also, my old <a href="http://davidbcalhoun.com/present/mobile-performance/">slides</a> have been somewhat embarrassing.  For some strange reason, at the time I wanted to give <a href="http://meyerweb.com/eric/tools/s5/">S5</a> a try &#8211; that outdated, ancient, not-performant slideshow framework.  The result is a slideshow on performance that loads slowly&#8230; doh!  (incidentally, I recommend <a href="http://imakewebthings.github.com/deck.js/">deck.js</a> as an alternative).</p>
<p>In any case, it was time for a roundup of mobile performance best practices, in blog form.  I&#8217;m not sure if it&#8217;s properly called a manifesto, but it is what it is!  Onward!</p>
<h3>For fun: Latency and bandwidth tests</h3>
<p>Before we start.. just a little fun data!  It&#8217;s always been a pleasure to fiddle around with <a href="https://github.com/yahoo/boomerang">boomerang.js</a> and compare results.  With my latest trip to Japan, I had the opportunity to run Boomerang on Japan&#8217;s <a href="http://en.wikipedia.org/wiki/EMOBILE_Limited">e-mobile</a> 3G network in the remotest of places, up in Hakuba/Nagano in the Japanese alps.</p>
<p>When I got back, I ran the same tests from downtown San Francisco, which was closer to my California-based test server, and should&#8217;ve been faster, right?  Theoretically&#8230;</p>
<h4>Boomerang Tests (running on a California-hosted server)</h4>
<table>
<th>
<td>Verizon 3G (SF)</td>
<td>ATT 3G (SF)</td>
<td>e-mobile 3G (Hakuba)</td>
</th>
<tr>
<td>Latency</td>
<td class="positive">251ms</td>
<td>901ms</td>
<td>401ms</td>
</tr>
<tr>
<td>Bandwidth</td>
<td>62kbps</td>
<td>3kbps</td>
<td class="positive">95kbps</td>
</tr>
</table>
<p>Yes, e-mobile didn&#8217;t have the greatest ping, but it handily beat ATT, even though it was going across the entire Pacific Ocean!  Note that it came out the best in the bandwidth tests however&#8230;  </p>
<p>(Note: it&#8217;s unknown if or how <a href="http://stevesouders.com/ms/">Steve Souders&#8217;s latest research</a> affects these findings)</p>
<p>There&#8217;s a lot of factors that could&#8217;ve been involved, so look to something like <a href="http://opensignalmaps.com/">OpenSignalMaps</a> for more data.</p>
<p>Ok, onto the tips!</p>
<h3>Page Organization</h3>
<p><img src="http://davidbcalhoun.com/wp-content/uploads/2011/10/mobile-site-organization.png" alt="" title="Smart phone versus feature phone website organization" width="645" height="633" class="aligncenter size-full wp-image-793" /></p>
<p>For feature phones that have little to no caching, aggressively combine requests (deliver HTML/CSS/JS all in one package).  For smart phones, take advantage of caching by mirroring desktop frontend best practices: separate HTML, CSS, and JS so they can be cached (per-session and across sessions).</p>
<p>There&#8217;s old research about <a href="http://www.yuiblog.com/blog/2008/02/06/iphone-cacheability/">extremely small cache sizes on iOS in particular</a>, but this research has been followed up on by more recent research by <a href="http://www.yuiblog.com/blog/2010/07/12/mobile-browser-cache-limits-revisited/">Ryan Grove (Yahoo!)</a> and <a href="http://www.stevesouders.com/blog/2010/07/12/mobile-cache-file-sizes/">Steve Souders (Google)</a>, which shows that we shouldn&#8217;t be so paranoid, since caching is pretty decent across all the major mobile browsers.</p>
<p>Of particular interest is a browser&#8217;s capability to cache files in a current session, browsing from page-to-page, which is what most users will end up doing (caching of the page across sessions is another matter).  What is the maximum file size a browser will cache during a session?  The <a href="http://www.browserscope.org/user/tests/table/agt1YS1wcm9maWxlcnINCxIEVGVzdBj_1OsBDA?v=3&#038;layout=simple&#038;f=Max%20js%20Cache%20Size%20(kB)">results (via Browserscope)</a> end up being encouraging:</p>
<table>
<th>
<td>Maximum Cache Size (MB)</td>
</th>
<tr>
<td>Android 2.1</td>
<td>4+</td>
</tr>
<tr>
<td>Android 2.2</td>
<td>2</td>
</tr>
<tr>
<td>Android 2.3</td>
<td>2</td>
</tr>
<tr>
<td>Android 3.0</td>
<td>4+</td>
</tr>
<tr>
<td>Blackberry 6.0.0</td>
<td>4+</td>
</tr>
<tr>
<td>iPad 4.3.5</td>
<td>4+</td>
</tr>
<tr>
<td>iPad 5.0</td>
<td>4+</td>
</tr>
<tr>
<td>iPhone 4.3.5</td>
<td>4+</td>
</tr>
<tr>
<td>iPhone 5.0</td>
<td>4+</td>
</tr>
<tr>
<td>Opera Mini 4</td>
<td>4+</td>
</tr>
<tr>
<td>Opera Mini 5</td>
<td>4+</td>
</tr>
<tr>
<td>Opera Mini 6</td>
<td>4+</td>
</tr>
<tr>
<td>webOS 2.0</td>
<td>1</td>
</tr>
</table>
<h3>Avoid redirects (foo.com -> m.foo.com)</h3>
<p>If possible, perform the redirection behind the scenes on the server, which should be transparent to the user.  When a user performs a Google search and clicks on your page, they&#8217;re already getting redirected once by Google (check it yourself).  Your own redirects are adding a second redirect where there need not be one.</p>
<h3>Optimize Images</h3>
<p><a href="http://filamentgroup.com/examples/responsive-images-new/demos/A-Default/demo.html"><img src="http://davidbcalhoun.com/wp-content/uploads/2011/10/responsive-images.jpg" alt="" title="Responsive images" width="600" height="423" class="aligncenter size-full wp-image-796" /></a><br />
Deliver appropriately-sized images to devices.  The philosophy of responsive design makes it easy to simply downscale images to fit the screen, but avoid this where possible, as this means wasted bandwidth.</p>
<p>You can optimize images through CSS media queries or in JavaScript (see below).  Though you want to reduce your dependence on cookies, it may be a good idea to store these width/height values into a cookie (or localStorage if you are fetching images in nontraditional ways) so the values can be read by the server, which can deliver appropriately-sized images.  This technique has been <a href="http://filamentgroup.com/lab/responsive_images_experimenting_with_context_aware_image_sizing/">implemented by Filament Group</a>, so you should probably read about their experiences before trying to roll your own.</p>
<p>Also note that where applicable, at the expense of performance you may want to serve higher resolution images for better screens, such as for Retina displays (which can be detected with JavaScript or CSS).</p>
<h4>JavaScript examples</h4>
<pre name="code" class="JScript">
window.innerHeight;       // max height actually available
window.innerWidth;        // max width actually available
window.devicePixelRatio;  // pixel density (standard is 1, high resolution is generally > 1)
</pre>
<p>(note that <code>screen.width</code> and <code>screen.height</code> are also available to tell you the dimensions of the entire screen, but this isn&#8217;t all available due to the space taken by the OS and browser chrome)</p>
<h4>Media query examples</h4>
<pre name="code" class="css">
@media only screen and (max-width: 480px) {
  /* small screen styles */
}

@media only screen and (min-width: 481px) {
  /* large screen styles */
}

@media (-webkit-min-device-pixel-ratio: 1.5),
       (-o-min-device-pixel-ratio: 3/2),
       (min--moz-device-pixel-ratio: 1.5),
       (min-device-pixel-ratio: 1.5) {
  /* high resolution styles */
}
</pre>
<h3>navigator.connection (Android only)</h3>
<p>Use <a href="http://davidbcalhoun.com/2010/using-navigator-connection-android">navigator.connection</a> if it&#8217;s available to serve different assets based on connection speed (3G vs WIFI, for instance).</p>
<p>Here&#8217;s the contents of the <code>navigator.connection</code> object (with a phone running on a 3G connection):</p>
<pre name="code" class="JScript">
{
  type: 4,
  UNKNOWN: 0,
  ETHERNET: 1,
  WIFI: 2,
  CELL_2G: 3,
  CELL_3G: 4
}
</pre>
<p>And an example of how you could write code for each type:</p>
<pre name="code" class="JScript">
(function(){  // sandbox our code
  if(!navigator.connection) navigator.connection = {type:0, UNKNOWN: 0};  // polyfill
  var connection = navigator.connection;

  if(connection.type === connection.WIFI || connection.type === connection.ETHERNET) {
    // high bandwidth
  } else {
    // normal bandwidth
  }
})();
</pre>
<p>Here&#8217;s how we might be able to use <a href="http://modernizr.com/">Modernizr</a> to help us out:</p>
<pre name="code" class="JScript">
(function(){  // sandbox our code
  if(!navigator.connection) navigator.connection = {type:0, UNKNOWN: 0};  // polyfill
  var connection = navigator.connection;

  // add a custom test to Modernizr
  Modernizr.addTest('highbandwidth', function(){
    return connection.type === connection.WIFI || connection.type === connection.ETHERNET;
  });

})();
</pre>
<p>We can now target special high-bandwidth assets with CSS:</p>
<pre name="code" class="css">
.highbandwidth .logo {background-image:url('logo-high.jpg');}
.no-highbandwidth .logo {background-image:url('logo.jpg');}
</pre>
<h3>base64 encode small UI images</h3>
<p>You can base64 encode binary image data in HTML and CSS:</p>
<h4>HTML</h4>
<pre name="code" class="html">
&lt;img src=&quot;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUA
AAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO
9TXL0Y4OHwAAAABJRU5ErkJggg==&quot; alt=&quot;Red dot&quot;&gt;
</pre>
<h4>CSS</h4>
<pre name="code" class="css">
.dot {
  background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUA
AAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO
9TXL0Y4OHwAAAABJRU5ErkJggg==');
}
</pre>
<p>There seems to be the mistaken belief floating around that base64 images aren&#8217;t cacheable.  However, because you can embed them in your CSS, base64 encoded images will be cached along with the rest of your CSS.</p>
<p>You&#8217;ll probably just want to limit this to small UI icons however.  I wrote a <a href="http://davidbcalhoun.com/2011/when-to-base64-encode-images-and-when-not-to">quick post on the drawbacks, and also a comparison with sprites</a>.</p>
<p>If you&#8217;re using Compass/SASS, base64 encoding images is pretty trivial and easy to maintain with the <a href="http://compass-style.org/reference/compass/helpers/inline-data/">inline-image helper</a>.</p>
<h3>Unicode and Emoji</h3>
<p>&#9734; (HTML entity: #9734)<br />
<img src="http://davidbcalhoun.com/wp-content/uploads/2011/10/emoji3.png" alt="" title="Emoji" width="18" height="18" /> (HTML entity: <code>#x1f468</code>)</p>
<p>Before even considering base64 images, take advantage of icons that are already made for you: unicode characters and <a href="http://pukupi.com/post/1964">emoji</a> (where supported).  Keep in mind that these will look different across browsers, so this might not be an option for everyone.</p>
<p>Because of inconsistent implementations of Emoji character codes between Asian carriers, representatives from Apple and Google made a <a href="http://en.wikipedia.org/wiki/Emoji#Emoji_in_the_Unicode_standard">proposal to add Emoji to the Unicode standard</a>.  Unfortunately it seems that only iPhone supports them for now.  Here&#8217;s a <a href="http://www.unicode.org/charts/PDF/U1F300.pdf">handy chart of all the Unicode emoji characters available</a>.</p>
<h3>Take advantage of CSS3</h3>
<p>CSS3 offers many replacements for things we needed images for previously.  RGBA values replace the need for a semitransparent image for overlays and such.  Likewise, border-radius, box shadow, linear-gradients, radial-gradients all reduce the need for images.</p>
<p>However, do be aware that though phones support these new features, it doesn&#8217;t mean they&#8217;re necessarily ready for primetime.  Something I&#8217;ve encountered recently to remind me of this fact is <a href="http://code.google.com/p/android/issues/detail?id=767">severe color banding issues when using a CSS radial gradient</a>.  The solution was to fake the radial gradient using two linear gradients, or to (unfortunately) use an old-fashioned image.</p>
<h3>Avoid using cookies</h3>
<p>Cookies get thrown into <em>every</em> request on a per-domain basis, so limit your usage of them.  Use localStorage/sessionStorage instead, where possible.</p>
<h3>App cache</h3>
<p>Take advantage of the HTML5 app cache, though it&#8217;s an unwieldy beast to tame.  This will mean you will need to make your site work offline, which might be tricky.</p>
<p>Assets that are traditionally cached get rechecked on page refresh (the server sends back a 304 response if your cache is still up-to-date).  Whereas with the app cache, only one file (your manifest) is rechecked on page load.</p>
<h3>Deferred JavaScript execution</h3>
<p><img src="http://davidbcalhoun.com/wp-content/uploads/2011/10/gmail-deferred-javascript-execution.png" alt="" title="Gmail deferred JavaScript execution" width="497" height="450" class="aligncenter size-full wp-image-810" /></p>
<p>We know that deferring downloading of scripts is advantageous (by placing scripts at the bottom of a page or by using the <code>async</code> attribute), but deferred execution of JavaScript is even more important.  Sure, we can use the <code>defer</code> attribute, but that&#8217;s only really relevant for when the page is loading (<code>defer</code> lets the browser know that the UI doesn&#8217;t depend on the JavaScript, so it can be safely deferred).</p>
<p>But what about JavaScript that runs after the page loads, such as XHR and JSONP requests?  What does this mean for the user?  It means that the UI freezes up unexpectedly when JavaScript is being downloaded and executed in the background.  But this doesn&#8217;t mean that you want to completely avoid background downloading of JavaScript.  The Gmail mobile team came up with a <a href="http://googlecode.blogspot.com/2009/09/gmail-for-mobile-html5-series-reducing.html">clever solution</a>: by commenting all of their code and dynamically eval&#8217;ing it when needed, they split up the JavaScript downloading from its execution.</p>
<h3>Perceived performance</h3>
<p>Do whatever you have to do to let the user know that the UI is still responding.  This sometimes means faking that something is happening.  Communication is key!  If they clicked on a button, give some indication that they clicked on it.  If they clicked on something that requires a request to the network, show a spinner right away, even if it means you haven&#8217;t even sent out a request.  The user doesn&#8217;t need to know the nitty-gritty details &#8211; they just want to know that their intent was communicated.</p>
<h3>Onclick delay</h3>
<p><iframe width="853" height="480" src="http://www.youtube.com/embed/k1M4L3TAyEU" frameborder="0" allowfullscreen></iframe></p>
<p>On several major mobile operating systems there&#8217;s a several hundred millisecond delay on the onclick event.  This is because of the double-tap-to-zoom functionality.  When a user first taps on the screen, there&#8217;s a hard-coded delay that waits for the second tap.  If there&#8217;s no second tap, the onclick event is then fired.  Unfortunately the only way to get around the delay is to tap into touch events instead, which is a bit more complicated than it appears on first glance.</p>
<p>For an overview of some of the challenges of implementing the workaround, see <a href="http://code.google.com/mobile/articles/fast_buttons.html">this article by Google&#8217;s Ryan Fioravanti</a>.</p>
<h3>Take advantage of hardware acceleration</h3>
<p>Use hardware-accelerated CSS transforms where possible (translate3d, translateZ, rotate3d, and scale3d).  An element that is hardware accelerated is turned into a graphic, which is perfect for the GPU to manipulate, taking away the burden from the CPU.</p>
<p>However, the GPU isn&#8217;t all-powerful, so don&#8217;t try to apply hardware accelerations to everything.  Also, these elements still need to be refreshed periodically, and it turns out that you can make some good optimizations here.  First, you&#8217;ll want to debug the composited layers on your desktop browser:</p>
<h4>Debugging hardware acceleration</h4>
<p><a href="http://www.webkit.org/blog-files/3d-transforms/poster-circle.html"><img src="http://davidbcalhoun.com/wp-content/uploads/2011/10/debug-composited-layers-hardware-acceleration.png" alt="" title="WebKit&#039;s poster circle demo with and without the debug information" width="767" height="399" class="aligncenter size-full wp-image-803" /></a><br />
<em>Chrome</em></p>
<ol>
<li>Type the following in the address bar: about:flags</li>
<li>&#8220;Composited render layer borders&#8221; -> Enable</li>
</ol>
<p><em>Safari</em></p>
<ol>
<li>Open a terminal</li>
<li>$ defaults write com.apple.Safari IncludeInternalDebugMenu 1</li>
<li>$ defaults write com.apple.Safari CA_COLOR_OPAQUE 1</li>
<li>Open (or restart) Safari</li>
<li>Debug -> Show Compositing Borders</li>
</ol>
<p>(to turn these off, run the same commands with a boolean FALSE: i.e. <code>defaults write com.apple.Safari CA_COLOR_OPAQUE FALSE</code>)</p>
<p>Keep in mind that each composited layer has a limited width and height.  For instance, if you&#8217;re creating an image carousel, chances are the dimensions of the element will be too big to fit the layer into memory as one piece.  This means that when the element is animated, the GPU has to break up the layer manually into several manageable chunks.  It&#8217;s much better to chunk it yourself.  To do this, you trigger hardware acceleration on each chunk.</p>
<p>So you will change this:</p>
<pre name="code" class="css">
.carousel {
  -webkit-transform: translate3d(0,0,0);  /* or translateZ(0); */
}
</pre>
<p>To this:</p>
<pre name="code" class="css">
.carousel {
  -webkit-transform: translate3d(0,0,0);  /* or translateZ(0); */
}

.carousel-pane {
  -webkit-transform: translate3d(0,0,0);  /* or translateZ(0); */
}
</pre>
<p>Where carousel-pane represents each child element of the carousel.</p>
<p>More info: <a href="http://dl.dropbox.com/u/5618867/mseeley-2011-09-27-html5devconf.pdf">(slides) WebKit in Your Living Room (Matt Seeley, Netflix)</a></p>
<p>Also see <a href="http://www.html5rocks.com/en/mobile/optimization-and-performance.html">HTML5 Techniques for Optimizing Mobile Performance</a>.</p>
<h3>HTTP Pipelining</h3>
<p><a href="http://www.blaze.io/mobile/http-pipelining-big-in-mobile/"><img src="http://davidbcalhoun.com/wp-content/uploads/2011/10/pipelining.png" alt="HTTP Pipelining diagram" title="HTTP Pipelining (via Blaze.io)" width="640" height="445" class="aligncenter size-full wp-image-783" /></a></p>
<p>Take advantage of <a href="http://www.blaze.io/mobile/http-pipelining-big-in-mobile/">HTTP Pipelining</a>, which is often overlooked, but has broad support on mobile.  This virtually eliminates round trip times, for all but the first request.</p>
<p>Opera and Android support pipelining, and the newly released iOS 5 has added support for it.</p>
<p>Great! So how do you make sure your server is taking advantage of pipelining?</p>
<blockquote><p>The first request to every server is sent by itself (only one request on the connection), and the browser looks for two properties in the response:</p>
<ol>
<li>Use of HTTP/1.1</li>
<li>An explicit “Connection: Keep-Alive” header (required by Android)</li>
</ol>
<p><a href="http://www.blaze.io/mobile/http-pipelining-big-in-mobile/">-Blaze.io</a>
</p></blockquote>
<p>If these criteria are met, subsequent requests will be pipelined.  Sweet!</p>
<h3>DNS Prefetching</h3>
<p>Take advantage of <a href="https://developer.mozilla.org/En/Controlling_DNS_prefetching">DNS Prefetching</a>.  This theoretically speeds up load times, but there have been <a href="http://www.mydigitallife.info/turn-off-dns-prefetching-in-google-chrome-to-fix-resolving-host-and-cannot-load-page-error/">some issues</a>, so be sure to test it.</p>
<p>To turn off DNS Prefetching, serve this meta tag:</p>
<pre name="code" class="html">
&lt;meta http-equiv=&quot;x-dns-prefetch-control&quot; content=&quot;off&quot;&gt;
</pre>
<p>You can also explicitly force a DNS lookup:</p>
<pre name="code" class="html">
&lt;link rel=&quot;dns-prefetch&quot; href=&quot;http://www.example.com/&quot;&gt;
</pre>
<h3>Avoid library code bloat</h3>
<p>If you&#8217;re developing for smart phones, you may be able to dramatically reduce the data over the wire by simply using new JavaScript APIs instead of a full-blown library or framework such as jQuery Mobile (which is rather a UI framework and depends on the desktop version of jQuery).</p>
<p>Among the things offered by newer browsers, which should reduce your dependence on a library:</p>
<ul>
<li><a href="https://developer.mozilla.org/En/DOM/Document.querySelector">querySelector</a>/<a href="https://developer.mozilla.org/en/DOM/document.querySelectorAll">querySelectorAll</a>: CSS selectors that replace the need for a selector engine</li>
<li><a href="https://developer.mozilla.org/en/DOM/document.getElementsByClassName">getElementsByClassName</a></li>
<li><a href="https://developer.mozilla.org/en/DOM/element.classList">classList</a> &#8211; replaces the need for hasClass, addClass, removeClass helpers (available on iOS5, but not sure what else)</li>
<li><a href="https://developer.mozilla.org/En/XMLHttpRequest/Using_XMLHttpRequest">XMLHttpRequest</a> &#8211; it&#8217;s probably time to learn how to do this natively instead of using a wrapper that takes care of  IE&#8217;s old implementation that requests an ActiveX object.  <a href="http://hacks.mozilla.org/2009/07/cross-site-xmlhttprequest-with-cors/">Cross-Origin Resource Sharing</a> also means we can easily share resources across domains.</li>
<li><a href="https://developer.mozilla.org/en/DOM/Manipulating_the_browser_history">HTML5 history (pushState, etc)</a> &#8211; though an <a href="https://bugs.webkit.org/show_bug.cgi?id=42940">older bug</a> means you should maybe hold off for now (note: the fix is present in iOS 5, which is based on a newer WebKit)</li>
<li><a href="http://www.the-art-of-web.com/html/html5-form-validation/">HTML5 Form Validation</a> reduces our need for JavaScript-based validation</li>
<li>HTML5 input types that reduce our need for custom UI controls (date, time, slider [range], etc)</li>
</ul>
<p>You&#8217;ll want to consider using either a library that was optimized for the browsers you&#8217;re targeting (such as <a href="http://zeptojs.com/">Zepto.js</a>) or simply bring in <a href="http://microjs.com/">a microlibrary for specific tasks you want to perform</a>.</p>
<h3>Clientside databases</h3>
<p>Most mobile browsers currently support WebSQL, which is being phased out in support of indexedDB, which is not widely implemented.  However, if you use a wrapper such as <a href="http://westcoastlogic.com/lawnchair/">Lawnchair</a>, the transition from one to the other is relatively painless.</p>
<h3>TODO: testing</h3>
<h3>More</h3>
<p>(to be expanded on later)</p>
<ul>
<li>use standard desktop best practices (for smart phones)</li>
<li>requestAnimationFrame instead of setTimeout</li>
<li>setImmediate (where available) instead of setTimeout(fn(){},0)</li>
<li>Ajax parsing times: you might want to use Multipart XHR so you can yield the process as it&#8217;s going through big responses (to prevent the UI locking up)</li>
<li>avoid rgba, box shadows, text shadow, etc, as this greatly degrades performance (especially on animations)</li>
<li>high resolution screens may suffer from animation/transition slowness &#8211; it&#8217;s been shown that manipulating the viewport tag to scale the page <a href="http://29a.ch/2011/5/27/fast-html5-canvas-on-iphone-mobile-safari-performance">will speed up canvas rendering</a>, and <a href="http://paulbakaus.com/2011/10/10/scroller-vs-scrollability-deathmatch/">high-dpi scaling concerns are also evident in CSS transforms</a></li>
<li><a href="http://joehewitt.com/2011/10/05/fast-animation-with-ios-webkit">WebKit animations are faster than animations done via JavaScript</a></li>
<li>if you do use JavaScript-based animations, limit the UI updates to ~17ms, which is equivalent to 60fps, which is the fastest your display will refresh anyway, so it&#8217;s pointless to try to do anything faster than that.  Keep track of the time since the last UI update and don&#8217;t do anything if 17ms haven&#8217;t passed.</li>
</ul>
<h3>On the horizon&#8230;</h3>
<ul>
<li><a href="http://www.chromium.org/spdy">SPDY</a>: already implemented in Amazon&#8217;s Silk browser for Kindle.  Will possibly be on Android phones <a href="http://androidandme.com/2011/10/news/google-chrome-is-finally-coming-to-an-android-device-near-you/">when the browser is powered by Chrome</a></li>
<li>indexedDB replacing WebSQL</li>
</ul>
<h3>Tools</h3>
<p><a href="http://stevesouders.com/mobileperf/mobileperfbkm.php">Mobile Perf bookmarklet</a><br />
<a href="http://calendar.perfplanet.com/2010/mobile-performance-analysis-using-pcapperf/">pcapperf (Packet Capture Web Performance Analyzer)</a><br />
<a href="http://www.blaze.io/mobile/">Blaze Mobitest</a> &#8211; tests the loading time of your site on actual phones</p>
<h3>More Resources</h3>
<p><a href="http://www.w3.org/TR/mwabp/">Mobile Web Application Best Practices</a><br />
<a href="http://stevesouders.com/mobileperf/">Mobile Performance (Steve Souders)</a><br />
<a href="http://www.strangeloopnetworks.com/web-performance-optimization-hub/topics/mobile/">Strangeloop Web Performance Hub / Mobile</a></p>
<p>(odometer image via <a href="http://www.flickr.com/photos/henrybloomfield/4442900025/">henrybloomfield on Flickr</a>)</p>
]]></content:encoded>
			<wfw:commentRss>http://davidbcalhoun.com/2011/mobile-performance-manifesto/feed</wfw:commentRss>
		<slash:comments>18</slash:comments>
		</item>
		<item>
		<title>New Mobile Safari stuff in iOS5: position:fixed, overflow:scroll, new input type support, web workers, ECMAScript 5</title>
		<link>http://davidbcalhoun.com/2011/new-mobile-safari-stuff-in-ios5-position-fixed-overflow-scroll-new-input-type-support-web-workers-ecmascript-5</link>
		<comments>http://davidbcalhoun.com/2011/new-mobile-safari-stuff-in-ios5-position-fixed-overflow-scroll-new-input-type-support-web-workers-ecmascript-5#comments</comments>
		<pubDate>Tue, 07 Jun 2011 12:22:08 +0000</pubDate>
		<dc:creator>David</dc:creator>
				<category><![CDATA[mobile]]></category>

		<guid isPermaLink="false">http://davidbcalhoun.com/?p=674</guid>
		<description><![CDATA[(note: this is based on the first iOS5 beta [9A5220p] and is subject to change on final release) It looks like there&#8217;s finally some major improvements in mobile Safari, some of which I&#8217;ve found below on my &#8220;first glance&#8221; after downloading the SDK. Chime in if you find anything yourself! Bad news first Much to [...]]]></description>
			<content:encoded><![CDATA[<p>(note: this is based on the first iOS5 beta [9A5220p] and is subject to change on final release)</p>
<p>It looks like there&#8217;s finally some major improvements in mobile Safari, some of which I&#8217;ve found below on my &#8220;first glance&#8221; after downloading the SDK.  Chime in if you find anything yourself!</p>
<h3>Bad news first</h3>
<p>Much to my disappointment, browser-based file uploads are still not supported (<a href="http://frontendstuff.com/html/examples/input-type-file.html">input type=&#8221;file&#8221;</a>), even though they have been supported on Android since version 2.2 (which they have <a href="http://davidbcalhoun.com/2011/android-3-0-honeycomb-is-first-to-implement-the-device-api">continued to improve and refine</a>).  The best use case for this is uploading pictures and videos straight from the browser, but Apple seems more interested in making those functions possible directly from the operating system itself, supporting only big names like Twitter and YouTube.  So much for the little guys.</p>
<p>There&#8217;s other stuff on my wishlist that hasn&#8217;t yet been implemented, such as <s>WebGL and</s> indexedDB, along with some HTML5 input types, but regardless it&#8217;s good to see some real progress in iOS 5.  (update: it appears that some WebGL features are starting to be supported, although the demos I tried didn&#8217;t seem to work).</p>
<p>Now let&#8217;s move on to the awesome new stuff that IS implemented!</p>
<h3>position:fixed</h3>
<p>A point of contention since the original iPhone was released in 2007, position:fixed now works on iOS5!  What this means to developers: it&#8217;s now very easy to create top and bottom toolbars for your web apps.  (there&#8217;s a long history of hacks and workarounds which will still need to be implemented as a fallback for the time being, but I&#8217;ll save that for another post.  I should also mention that position:fixed has worked on Android since version 2.2, and webOS seems to support a somewhat hacky implementation).</p>
<p>Here&#8217;s a <a href="http://www.youtube.com/watch?v=JFzv3ETwfms">video demo of position:fixed on iOS5</a>:</p>
<p><iframe width="640" height="510" src="http://www.youtube.com/embed/JFzv3ETwfms" frameborder="0" allowfullscreen></iframe></p>
<p>(check out the <a href="http://frontendstuff.com/css/examples/position-fixed.html">demo</a> for yourself)</p>
<h3>overflow:scroll</h3>
<p>This is a similar problem to position:fixed, but now it works on iOS5!  For content that doesn&#8217;t fit in its container element, previously the content was completely cut off (similarly with iframes).  On the desktop we have the option to show scrollbars instead, allowing the user to scroll to see the content, but iOS made this difficult by requiring two fingers to scroll.  Now overflow:scroll works and the user can scroll through the container&#8217;s content with a single finger.  Developers can use new CSS to enable native scrolling (with scrollbars and momentum): <code>-webkit-overflow-scrolling: touch;</code> (via <a href="http://johanbrook.com/browsers/native-momentum-scrolling-ios-5/">Johan Brook</a>).</p>
<p>It&#8217;s assumed that it&#8217;s up to the developer to implement some sort of visual indicator to let the user know they can interact with the element.</p>
<p>One criticism so far: there&#8217;s no inertia scroll on this element, so it doesn&#8217;t quite feel the same as scrolling the page.</p>
<p>Here&#8217;s a quick <a href="http://www.youtube.com/watch?v=KwpZ1F6dW5U">video demo of overflow:scroll on iOS 5</a>.</p>
<p><iframe width="640" height="510" src="http://www.youtube.com/embed/KwpZ1F6dW5U" frameborder="0" allowfullscreen></iframe></p>
<p>(check out the <a href="http://frontendstuff.com/css/examples/overflow-scroll.html">demo</a> for yourself)</p>
<h3>New Input Types</h3>
<p>HTML5 defined many new helpful input types, and mobile operating systems have been slowly implementing them and creating optimized keyboards for the inputs.  iOS5 now supports these input types: date, datetime, month, time, range.  Click on the images to see their respective demo pages:</p>
<p><a href="http://frontendstuff.com/html/input-type-date.html"><img src="http://davidbcalhoun.com/wp-content/uploads/2011/06/ios-date-input.png" alt="iOS Date Input" title="iOS Date Input" width="320" height="480" class="size-full wp-image-677" /></a><a href="http://frontendstuff.com/html/input-type-datetime.html"><img src="http://davidbcalhoun.com/wp-content/uploads/2011/06/ios-datetime-input.png" alt="iOS Datetime Input" title="iOS Datetime Input" width="320" height="480" class="size-full wp-image-678" /></a><a href="http://frontendstuff.com/html/input-type-month.html"><img src="http://davidbcalhoun.com/wp-content/uploads/2011/06/ios-month-input.png" alt="iOS Month Input" title="iOS Month Input" width="320" height="480" class="size-full wp-image-680" /></a><a href="http://frontendstuff.com/html/input-type-time.html"><img src="http://davidbcalhoun.com/wp-content/uploads/2011/06/ios-time-input.png" alt="iOS Time Input" title="iOS Time Input" width="320" height="480" class="size-full wp-image-682" /></a><a href="http://frontendstuff.com/html/input-type-range.html"><img src="http://davidbcalhoun.com/wp-content/uploads/2011/06/ios-range-input.png" alt="iOS Range Input" title="iOS Range Input" width="320" height="480" class="size-full wp-image-681" /></a></p>
<p>And a fun one &#8211; <a href="http://davidbcalhoun.com/2011/implementing-iphone-slider-unlock-with-input-type-range">my iPhone slider hack based on input type range</a>, which now actually works on the iPhone itself (because input type=&#8221;range&#8221; is now supported)!</p>
<p><a href="http://davidbcalhoun.com/a/iphone-slider.html"><img src="http://davidbcalhoun.com/wp-content/uploads/2011/06/ios-iphone-slider-in-html.png" alt="iOS Slider implemented with Range Input" title="iOS Slider implemented with Range Input" width="320" height="480" class="aligncenter size-full wp-image-679" /></a></p>
<h3>Web Workers (JavaScript)</h3>
<p>JavaScript is single-threaded, and it happens to run on the same thread as the UI, which means computationally expensive operations can lead to an unresponsive UI, and no one likes that.  Web Workers help by offloading tasks to another thread and only returning output when it needs to.  In other words, it&#8217;s a good thing for us web developers.</p>
<p>According to my own tests, Web Workers seemed to be briefly enabled on early versions of iOS3, but were soon disabled thereafter.  Now with iOS5, they&#8217;re back again!</p>
<h3>New ECMAScript 5 stuff (JavaScript)</h3>
<p>(based on <a href="http://kangax.github.com/es5-compat-table/">kangax&#8217;s ECMAScript 5 compatibility table</a>)</p>
<table>
<thead>
<tr>
<td>Feature</td>
<td>iOS 4.3.2</td>
<td>iOS 5 beta 1</td>
</tr>
</thead>
<tfoot></tfoot>
<tbody>
<tr>
<td>Object.create</td>
<td class="positive">Yes</td>
<td class="positive">Yes</td>
</tr>
<tr>
<td>Object.defineProperty</td>
<td class="positive">Yes</td>
<td class="positive">Yes</td>
</tr>
<tr>
<td>Object.defineProperties</td>
<td class="positive">Yes</td>
<td class="positive">Yes</td>
</tr>
<tr>
<td>Object.getPrototypeOf</td>
<td class="positive">Yes</td>
<td class="positive">Yes</td>
</tr>
<tr>
<td>Object.keys</td>
<td class="positive">Yes</td>
<td class="positive">Yes</td>
</tr>
<tr>
<td>Object.seal</td>
<td class="negative">No</td>
<td class="positive">Yes</td>
</tr>
<tr>
<td>Object.freeze</td>
<td class="negative">No</td>
<td class="positive">Yes</td>
</tr>
<tr>
<td>Object.preventExtensions</td>
<td class="negative">No</td>
<td class="positive">Yes</td>
</tr>
<tr>
<td>Object.isSealed</td>
<td class="negative">No</td>
<td class="positive">Yes</td>
</tr>
<tr>
<td>Object.isFrozen</td>
<td class="negative">No</td>
<td class="positive">Yes</td>
</tr>
<tr>
<td>Object.isExtensible</td>
<td class="negative">No</td>
<td class="positive">Yes</td>
</tr>
<tr>
<td>Object.getOwnPropertyDescriptor</td>
<td class="positive">Yes</td>
<td class="positive">Yes</td>
</tr>
<tr>
<td>Object.getOwnPropertyNames</td>
<td class="positive">Yes</td>
<td class="positive">Yes</td>
</tr>
<tr>
<td>Date.prototype.toISOString</td>
<td class="positive">Yes</td>
<td class="positive">Yes</td>
</tr>
<tr>
<td>Date.prototype.toISOString</td>
<td class="positive">Yes</td>
<td class="positive">Yes</td>
</tr>
<tr>
<td>Date.prototype.toISOString</td>
<td class="positive">Yes</td>
<td class="positive">Yes</td>
</tr>
<tr>
<td>Date.now</td>
<td class="positive">Yes</td>
<td class="positive">Yes</td>
</tr>
<tr>
<td>JSON</td>
<td class="positive">Yes</td>
<td class="positive">Yes</td>
</tr>
<tr>
<td>Function.prototype.bind</td>
<td class="negative">No</td>
<td class="negative">No</td>
</tr>
<tr>
<td>String.prototype.trim</td>
<td class="positive">Yes</td>
<td class="positive">Yes</td>
</tr>
<tr>
<td>Array.prototype.indexOf</td>
<td class="positive">Yes</td>
<td class="positive">Yes</td>
</tr>
<tr>
<td>Array.prototype.lastIndexOf</td>
<td class="positive">Yes</td>
<td class="positive">Yes</td>
</tr>
<tr>
<td>Array.prototype.every</td>
<td class="positive">Yes</td>
<td class="positive">Yes</td>
</tr>
<tr>
<td>Array.prototype.some</td>
<td class="positive">Yes</td>
<td class="positive">Yes</td>
</tr>
<tr>
<td>Array.prototype.forEach</td>
<td class="positive">Yes</td>
<td class="positive">Yes</td>
</tr>
<tr>
<td>Array.prototype.map</td>
<td class="positive">Yes</td>
<td class="positive">Yes</td>
</tr>
<tr>
<td>Array.prototype.filter</td>
<td class="positive">Yes</td>
<td class="positive">Yes</td>
</tr>
<tr>
<td>Array.prototype.reduce</td>
<td class="positive">Yes</td>
<td class="positive">Yes</td>
</tr>
<tr>
<td>Array.prototype.reduceRight</td>
<td class="positive">Yes</td>
<td class="positive">Yes</td>
</tr>
<tr>
<td>Getter in property initializer</td>
<td class="positive">Yes</td>
<td class="positive">Yes</td>
</tr>
<tr>
<td>Setter in property initializer</td>
<td class="positive">Yes</td>
<td class="positive">Yes</td>
</tr>
<tr>
<td>Property access on strings</td>
<td class="positive">Yes</td>
<td class="positive">Yes</td>
</tr>
<tr>
<td>Reserved words as property names</td>
<td class="negative">No</td>
<td class="positive">Yes</td>
</tr>
<tr>
<td>Strict mode</td>
<td class="negative">No</td>
<td class="positive">Yes</td>
</tr>
</tbody>
</table>
<h3>HTML5Test score</h3>
<p>iOS 4.3.2 scores 206 (7 bonus points) on the <a href="http://html5test.com/">HTML5 Test</a>, whereas iOS 5 beta scores 267 (9 bonus points).  Much of these gains seem to be made in the &#8220;Forms&#8221; and &#8220;Parsing rules&#8221; sections, as well as the &#8220;Web Workers&#8221; section.</p>
<h3>Miscellaneous new stuff</h3>
<ul>
<li>Inline SVG in text/html</li>
<li>float32array, int8array, int16array, int32array in JavaScript</li>
<li>window.matchmedia() (JavaScript)</li>
<li><s>onsearch Event (JavaScript)</s> &#8211; it looks like this was just broken in later iOS 4.3 builds, but it&#8217;s back now in iOS 5</li>
<li>MathML elements recognized (based on  <a href="http://html5test.com/">html5test</a>)</li>
<li>Improved speed of Canvas rendering (<a href="https://twitter.com/#!/KesieV/status/78067470501543936">source</a>)</li>
<li>UIWebView and home screen web apps now running on Nitro? (expected but not tested)</li>
<li>Newly supported CSS gradient syntax (-webkit-linear-gradient versus the older -webkit-gradient syntax)</li>
<li><a href="https://developer.mozilla.org/en/DOM/element.classList">classList</a> (JavaScript)</li>
<li>A major WebKit HTML5 History (popstate) bug is <a href="https://bugs.webkit.org/show_bug.cgi?id=42940">now fixed</a></li>
<li><a href="http://html5demos.com/contenteditable">contentEditable</a> now works properly</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://davidbcalhoun.com/2011/new-mobile-safari-stuff-in-ios5-position-fixed-overflow-scroll-new-input-type-support-web-workers-ecmascript-5/feed</wfw:commentRss>
		<slash:comments>82</slash:comments>
		</item>
		<item>
		<title>Notes: Mobile Web Design (Cameron Moll, 2007)</title>
		<link>http://davidbcalhoun.com/2011/notes-mobile-web-design-cameron-moll-200</link>
		<comments>http://davidbcalhoun.com/2011/notes-mobile-web-design-cameron-moll-200#comments</comments>
		<pubDate>Fri, 21 Jan 2011 09:43:56 +0000</pubDate>
		<dc:creator>David</dc:creator>
				<category><![CDATA[mobile]]></category>

		<guid isPermaLink="false">http://davidbcalhoun.com/?p=610</guid>
		<description><![CDATA[What&#8217;s this? These are some notes I collect as I read through Cameron Moll&#8217;s Mobile Web Design. Introduction 8. Further info: Designing the Mobile User Experience (Barbara Ballard) dotMobi Web Developer&#8217;s Guide (dev.mobi) Global Authoring Practices for the Mobile Web (Luca Passani) (passani.it/gap) Constant Touch: A Global History of the Mobile Web (Jon Agar) Personal, [...]]]></description>
			<content:encoded><![CDATA[<h3>What&#8217;s this?</h3>
<p>These are some notes I collect as I read through Cameron Moll&#8217;s <a href="http://www.amazon.com/Mobile-Web-Design-Cameron-Moll/dp/0615185916">Mobile Web Design</a>.</p>
<h3>Introduction</h3>
<p>8. Further info:</p>
<p>Designing the Mobile User Experience (Barbara Ballard)<br />
dotMobi Web Developer&#8217;s Guide (dev.mobi)<br />
Global Authoring Practices for the Mobile Web (Luca Passani) (passani.it/gap)<br />
Constant Touch: A Global History of the Mobile Web (Jon Agar)<br />
Personal, Portable, Pedestrian: Mobile Phones in Japanese Life (Mizuko Ito)<br />
Mobile Interaction Design (Matt Jones)</p>
<p>13. iPhone released just before publication</p>
<h3>Mobile Web Fundamentals</h3>
<p>15. <a href="http://communities-dominate.blogs.com/brands/2007/01/putting_27_bill.html">Putting 2.7 Billion in Context: Mobile Phone Users</a></p>
<p>18. Phone is smaller.  Different input methods.  Searching for specific data (directions or a phone number) rather than a truckload of data available via the desktop.  One handed interaction.</p>
<p>19. Limitations: small screen size, difficulty of data input, user agent inconsistency</p>
<p>Opportunities: location-specific data, on-the-go-messaging, voice communication.</p>
<p>20. Weather Channel &#8211; greater reach on mobile web compared to desktop (<a href="http://www.comscore.com/Press_Events/Press_Releases/2007/05/Mobile_Web_Usage_Grows_in_UK">source</a>)</p>
<p>21. Rollable display &#8211; Polymer Vision Readius (<a href="http://www.youtube.com/watch?v=uQMBzXaCmqY">video</a>)</p>
<p>Many devices and user agents, making testing expensive and impractical.  Emulators and testing on multiple devices will lead to successful deployment.</p>
<p>22. Opera Mini &#8211; far better UI than most native browsers</p>
<p>Mostly must be installed manually, except for T-Mobile shipping hundreds of thousands with it pre-installed</p>
<p>23. &#8220;…the mobile web experience is often a small screen, intermittent, one-handed experience&#8221;</p>
<p>24. understanding of target audience, their usage and what they want, and the contextual relevance (phone numbers, etc.) of data</p>
<p>25. Initiate a phone call: wtai scheme for WML, tel scheme for HTML.</p>
<p>Some browsers (Opera Mini, Safari Mobile) automatically convert links to phone numbers</p>
<p>WML scheme to add a number to the address book: wtai://wp/ap;+5555555;Amy%20Miller</p>
<p>26. carrier myopia: devs thinking the only way to reach the audience is by landing on the carrier deck.  Mobile User Experience Conference (MEX) 2007: &#8220;Tearing down the walled garden will enhance the mobile content experience and release value for the industry. The objective should be a free market for content and applications, based on open standards and accessible to all. We think the current fragmentation of formats and channels to market is holding back growth.&#8221;</p>
<p>29. &#8220;cell phone&#8221; is an outdated term.  Use &#8220;mobile&#8221; or &#8220;device&#8221;.</p>
<p>30. Japanese market: &#8220;keitai&#8221; (=&#8221;something you carry with you&#8221;)</p>
<h3>Four Methods, Revisited</h3>
<p>31. <a href="http://www.cameronmoll.com/archives/000398.html">Mobile Web Design ~ The Series</a> (Cameron Moll, 2005)</p>
<p>32. Method 1: Do nothing.  If the markup is meaningful and standards-based, the better mobile browsers can adapt.</p>
<p>33. Good browsers such as the iPhone&#8217;s allow the viewing of the full site (with zooming).</p>
<p>34. Advantages: mobile browsers shoulder the burden of reformatting content, no additional effort needed, users have same content and possibly the same experience as on a PC</p>
<p>Disadvantages: doesn&#8217;t address contextual relevance or exploit device capabilities, users with zoom-enabled devices are a small market share</p>
<p>35. Method 2: Reduce images and styling</p>
<p>-presentation styling and images reduced on the fly</p>
<p>mowser.com (Russell Beattie, formerly Yahoo! Mobile)<br />
skweezer.net &#8211; an older service dating back to 2001</p>
<p>2-minute mobile mod: <a href="http://www.mikeindustries.com/blog/archive/2005/07/make-your-site-mobile-friendly">http://www.mikeindustries.com/blog/archive/2005/07/make-your-site-mobile-friendly</a></p>
<p>36. Advantages: relies on implied hierarchy in HTML markup, viewable by a variety of devices, faster download, many browsers override CSS anyway, so why bother?</p>
<p>Disadvantages: ignores contextual relevance of mobility, file size may still be excessive</p>
<p>Method 3: Use Handheld Style Sheets</p>
<p>37. media=&#8221;handheld&#8221; style sheet</p>
<p>38. Not widely supported.</p>
<p>Advantages: handheld style sheet is built into CSS, at most one extra style sheet, one web address<br />
Disadvantages: ignores contextual relevance of mobility, media=&#8221;handheld&#8221; support is inconsistent and nearly unreliable</p>
<p>Method 4: Create Mobile-Optimized Content</p>
<p>39. Kayak.com/moby</p>
<p>41.  Advantages: contextually relevant (addresses first how the content is consumed, and presentation secondly), pages are leaner</p>
<p>Disadvantages: denies access to content by making assumptions about the user and device, two sets of files, alternate web addresses</p>
<p>42. Author&#8217;s opinion: doing nothing and mobile-optimized content are the two viable approaches</p>
<h3>XHTML/CSS Development</h3>
<p>43. WML deck and card metaphor.  Decline giving way to XHTML.  WAP protocol, WML language.</p>
<p>44.  With WAP 2.0, XHTML-MP is the preferred markup language</p>
<p>45. <a href="http://www.cameronmoll.com/mobile/mkp">Markup Test Pages</a>, <a href="http://www.cameronmoll.com/archives/000577.html">Mobile Web Design: Tips &#038; Techniques (2005)</a></p>
<p>47. No need to define new standards just for the web.  Same regardless of device: &#8220;The underlying standards for the greater web, regardless of device, person, or place, are the same: semantic markup, separation of structure and presentation, accessibility, and so on.&#8221;</p>
<p><a href="http://www.w3.org/TR/mobile-bp/">W3C Mobile Web Best Practices 1.0</a></p>
<p><a href="http://passani.it/gap">Global Authoring Practices for the Mobile Web (Luca Passani)</a></p>
<p>48. XHTML-MP template</p>
<pre name="code" class="HTML">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; ?&gt;
&lt;!DOCTYPE html PUBLIC &quot;-//WAPFORUM//DTD XHTML Mobile 1.0//EN&quot; &quot;http://www.wapforum.org/DTD/xhtml-mobile10.dtd&quot;&gt;
&lt;html xmlns=&quot;http://www.w3.org/1999/xhtml&quot;&gt;
&lt;head&gt;
  &lt;title&gt;Site Title&lt;/title&gt;
  &lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;mobile.css&quot;/&gt;
  &lt;meta http-equiv=&quot;Cache-Control&quot; content=&quot;max-age=600&quot; /&gt;
&lt;/head&gt;
&lt;body&gt;
  &lt;h1&gt;Page Heading&lt;/h1&gt;
  &lt;p&gt;Content&lt;/p&gt;
&lt;/body&gt;
&lt;/html&gt;
</pre>
<p>49. <a href="http://www.developershome.com/wap/xhtmlmp">DeveloperHome.com&#8217;s XHTML-MP Tutorial</a></p>
<p>50. <a href="http://htmllint.itc.keio.ac.jp/htmllink/tagslist.cgi?HTMLVersion=XHTML-MP">XHTML-MP Tags List</a></p>
<p>Good case examples:<br />
<a href="http://flickr.com/mob">Flickr Mobile</a><br />
<a href="http://mobile.fandango.com">Fandango Mobile</a></p>
]]></content:encoded>
			<wfw:commentRss>http://davidbcalhoun.com/2011/notes-mobile-web-design-cameron-moll-200/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Mobile JavaScript libraries and frameworks (Mobile Web Part 7)</title>
		<link>http://davidbcalhoun.com/2010/mobile-javascript-libraries-and-frameworks</link>
		<comments>http://davidbcalhoun.com/2010/mobile-javascript-libraries-and-frameworks#comments</comments>
		<pubDate>Tue, 07 Dec 2010 03:39:42 +0000</pubDate>
		<dc:creator>David</dc:creator>
				<category><![CDATA[mobile]]></category>

		<guid isPermaLink="false">http://davidbcalhoun.com/?p=513</guid>
		<description><![CDATA[Intro This is designed to be a &#8220;living&#8221; post of available materials which will hopefully be updated frequently. Right now there&#8217;s not much, just some links, but I hope to keep adding materials, so check back! The List Sencha Touch PhoneGap &#8211; native wrapper which provides access to native hardware through their own JavaScript APIs [...]]]></description>
			<content:encoded><![CDATA[<h3>Intro</h3>
<p>This is designed to be a &#8220;living&#8221; post of available materials which will hopefully be updated frequently.</p>
<p>Right now there&#8217;s not much, just some links, but I hope to keep adding materials, so check back!</p>
<h3>The List</h3>
<p><a href="http://www.sencha.com/products/touch/">Sencha Touch</a><br />
<a href="http://www.phonegap.com/">PhoneGap</a> &#8211; native wrapper which provides access to native hardware through their own JavaScript APIs<br />
<a href="http://jquerymobile.com/">jQuery Mobile</a> &#8211; a separate mobile UI which has jQuery as a dependency<br />
<a href="http://developer.apple.com/iad/">iAd</a> &#8211; an update to Apple&#8217;s PastryKit, but probably intended only for ads<br />
<a href="http://zeptojs.com/">Zepto.js</a><br />
<a href="http://joapp.com/">Jo HTML5 Mobile App Framework</a><br />
<a href="http://touch.sproutcore.com/hedwig/">Sproutcore Touch</a><br />
<a href="http://unify.github.com/unify/">Unify</a><br />
<a href="http://developer.yahoo.com/yui/3/">YUI3</a> &#8211; the desktop library has taken its first steps in supporting mobile (there&#8217;s no separate version just for mobile)<br />
<a href="http://www.springsource.org/spring-mobile">Spring Mobile</a>: an extension to Spring MVC.<br />
<a href="http://pyxismobile.com/">pyxis mobile</a><br />
<a href="http://www.winktoolkit.org/">Wink Toolkit</a><br />
<a href="http://chocolatechipmobile.wordpress.com/">ChocolateChip Mobile</a><br />
<a href="http://webapp-net.com/">WebApp.Net</a><br />
<a href="http://paularmstrongdesigns.com/projects/basejs/">baseJS</a><br />
<a href="http://xuijs.com/">XUI</a><br />
<a href="http://iwebkit.net/">iWebKit</a><br />
<a href="http://www.jqtouch.com/">jQTouch</a><br />
<a href="http://notes.sencha.com/post/1483278482/wed-like-to-extend-a-warm-welcome-to-one-of-our">MooTouch</a> &#8211; acquired and integrated into Sencha<br />
<a href="http://code.google.com/p/iphone-universal/">UiUIKit (Universal iPhone UI Kit)</a><br />
<a href="http://code.google.com/p/ciui-dev/">CiUI</a> &#8211; CNET iPhone UI<br />
<a href="">UiUIKit</a><br />
<a href="http://www.iui-js.org/">iUI</a> (<a href="http://code.google.com/p/iui/">on Google Code</a>) &#8211; the first library for the iPhone as far as I know.<br />
<a href="http://davidbcalhoun.com/2009/pastrykit-digging-into-an-apple-pie">PastryKit</a> &#8211; Apple&#8217;s proprietary framework, peeked into just for curiousity (not recommended for use)</p>
<h3>More from the Mobile Web series:</h3>
<p><a href="http://davidbcalhoun.com/2010/viewport-metatag">Part 1: The viewport metatag</a><br />
<a href="http://davidbcalhoun.com/2010/the-mobile-developers-toolkit-mobile-web-part-2">Part 2: The mobile developer’s toolkit</a><br />
<a href="http://davidbcalhoun.com/2010/designing-buttons-that-dont-suck">Part 3: Designing buttons that don’t suck</a><br />
<a href="http://davidbcalhoun.com/2010/on-designing-a-mobile-webpage">Part 4: On designing a mobile webpage</a><br />
<a href="http://davidbcalhoun.com/2010/using-mobile-specific-html-css-javascript">Part 5: Using mobile-specific HTML, CSS, and JavaScript</a><br />
<a href="http://davidbcalhoun.com/2010/dealing-with-device-orientation">Part 6: Dealing with device orientation</a><br />
<a href="http://davidbcalhoun.com/2010/mobile-javascript-libraries-and-frameworks">Part 7: Mobile JavaScript libraries and frameworks</a></p>
]]></content:encoded>
			<wfw:commentRss>http://davidbcalhoun.com/2010/mobile-javascript-libraries-and-frameworks/feed</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>Mobile Monday: Best Practices for Mobile Design (September 20, 2010)</title>
		<link>http://davidbcalhoun.com/2010/mobile-monday-best-practices-mobile-design-september-20-2010</link>
		<comments>http://davidbcalhoun.com/2010/mobile-monday-best-practices-mobile-design-september-20-2010#comments</comments>
		<pubDate>Tue, 21 Sep 2010 07:07:49 +0000</pubDate>
		<dc:creator>David</dc:creator>
				<category><![CDATA[mobile]]></category>

		<guid isPermaLink="false">http://davidbcalhoun.com/?p=463</guid>
		<description><![CDATA[Mobile Monday panel left to right: Wesley Yun (RIM), Jared Benson (Punchcut), Anne Sullivan (Microsoft/Tellme Networks), Chris Nesladek (Google), Sue Booker (Nokia) (taken with my iPhone 3GS) I just came back from Mobile Monday Silicon Valley: Best Practices for Mobile Design at the Computer History Museum in Mountain View. This was a panel discussion with [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://davidbcalhoun.com/wp-content/uploads/2010/09/momo.jpg"><img src="http://davidbcalhoun.com/wp-content/uploads/2010/09/momo-1024x768.jpg" alt="" title="momo" width="100%" class="size-large wp-image-464" /></a><i>Mobile Monday panel left to right: Wesley Yun (RIM), Jared Benson (Punchcut), Anne Sullivan (Microsoft/Tellme Networks), Chris Nesladek (Google), Sue Booker (Nokia) (taken with my iPhone 3GS)</i></p>
<p>I just came back from <a href="http://www.mobilemonday.us/?p=424">Mobile Monday Silicon Valley: Best Practices for Mobile Design</a> at the <a href="http://www.computerhistory.org/">Computer History Museum</a> in Mountain View.  This was a panel discussion with representatives from Google, Microsoft, Nokia, RIM, and Punchcut.  There were quite a few little nuggets of wisdom which I tried to write down in bullet form:</p>
<h4>Sue Booker, UED (Nokia)</h4>
<ul>
<li>1 trillion revenue worldwide from disabled users.  60m disabled users in the US.</li>
<li>assume the user is multitasking</li>
<li>apps will be used in totally unexpected ways</li>
<li>not just physical disabilities.. also people in different situations or environmental limitations (no voice, no audio, limited bandwidth, etc)</li>
<li>introduce new complicated functionality gradually.  It&#8217;s easy to tell if it&#8217;s a new user or a repeat user, so slowly give repeat users more info.</li>
<li>final takeaway: think of all types of users</li>
</ul>
<h4>Chris Nesladek, Commerce UI Lead (Google)</h4>
<ul>
<li>1. keep it simple</li>
<li>2. content is king</li>
<li>3. make it fun</li>
<li>4. make it fast</li>
<li>5. do one thing as an experiment</li>
<li>new UI challenge in the future: flexible screens?</li>
<li>discoverability of new features&#8230; for an Android feature: link to video demo on vimeo</li>
<li>final takeaway: designers, make friends with developers, because that&#8217;s how the best products get made</li>
</ul>
<h4>Anne Sullivan, UI Designer (Microsoft/Tellme Networks)</h4>
<ul>
<li>her focus: designing for speech on mobile</li>
<li>problem: discoverability of speech</li>
<li>understand the capabilities and limitations of speech</li>
<li>graceful degradation for speech: what happens when a voice command isn&#8217;t recognized?</li>
<li>be transparent about what happens about processing in the background.  For instance, geolocation.  Allow the user to change or override this info.</li>
<li>paper prototypes are very helpful</li>
<li>discoverability of voice command activation is hard.. have to test on device itself (i.e. to find the right button placement, etc.)</li>
<li>final takeaway: forget powerpoint!  do presentations on the phone itself</li>
</ul>
<h4><a href="http://twitter.com/benson">Jared Benson</a>, Design (Punchcut)</h4>
<ul>
<li>iterate quickly</li>
<li>no substitute for device itself</li>
<li>final takeaway: involve designers from the beginning</li>
</ul>
<h4><a href="http://twitter.com/nuysew">Wesley Yun</a>, UX (RIM)</h4>
<ul>
<li>don&#8217;t make assumptions about touch interfaces (common gestures).  The touchscreen is still pretty new, so not everyone is used to this yet</li>
<li>don&#8217;t be too clever for your users.  Think of users first, and do what makes sense.</li>
<li>prototype and fail quickly.  If you&#8217;re not failing, you&#8217;re not innovating</li>
<li>make sure unusual new interaction isn&#8217;t a core functionality (for instance, four-fingered scroll)</li>
<li>if you make something redundant, you&#8217;ve failed as a designer</li>
<li>final takeaway: make it obvious to users</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://davidbcalhoun.com/2010/mobile-monday-best-practices-mobile-design-september-20-2010/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Dealing with device orientation (Mobile web part 6)</title>
		<link>http://davidbcalhoun.com/2010/dealing-with-device-orientation</link>
		<comments>http://davidbcalhoun.com/2010/dealing-with-device-orientation#comments</comments>
		<pubDate>Tue, 24 Aug 2010 08:41:51 +0000</pubDate>
		<dc:creator>David</dc:creator>
				<category><![CDATA[mobile]]></category>
		<category><![CDATA[media queries]]></category>
		<category><![CDATA[orientation]]></category>

		<guid isPermaLink="false">http://davidbcalhoun.com/?p=410</guid>
		<description><![CDATA[Introduction If you read part 4 of this series, you&#8217;ll know that because of the variety of screen sizes, the best way to develop for mobile is to develop fluid layouts that take 100% of the available space on the screen. What you probably didn&#8217;t think of is that there&#8217;s different screen widths even on [...]]]></description>
			<content:encoded><![CDATA[<h3>Introduction</h3>
<p>If you read <a href="http://davidbcalhoun.com/2010/on-designing-a-mobile-webpage">part 4</a> of this series, you&#8217;ll know that because of the variety of screen sizes, the best way to develop for mobile is to develop fluid layouts that take 100% of the available space on the screen.</p>
<p>What you probably didn&#8217;t think of is that there&#8217;s different screen widths <em>even on the same device</em>!  This is due to screen orientation.  And when the user changes the screen orientation, stuff may break (hey, it&#8217;s not a perfect world).  In my experience this has meant needing to tweak percentage widths on elements, but I imagine there&#8217;s even more needs.  Imagine an image carousel that can only fit three images across in portrait mode but can possibly fit four images in landscape mode.  It might be nice to re-initialize the carousel to accommodate a forth image when the phone is in landscape mode (then again, that might create a lot of unnecessary overhead&#8230;).</p>
<p>In any case, I hope you can agree that it would sometimes be useful to know the screen orientation.</p>
<h3><code>window.orientation</code> and the <code>orientationchange</code> event</h3>
<p>Luckily on the latest smartphones you have some goodies available to you that you don&#8217;t have on the desktop (since desktop users aren&#8217;t in the habit of constantly turning their screens sideways!).</p>
<p><b><code>window.orientation</code></b>: this property gives the current screen orientation: 0 in portrait mode, 90 when rotated left, -90 when rotated right (no special value when the screen is upside-down)</p>
<p><b><code>orientationchange event</code></b>: this window event fires after every 90 degrees of rotation and, like other events, <a href="http://en.wikipedia.org/wiki/DOM_events">can be applied in various ways</a>:</p>
<pre name="code" class="JScript">
// DOM Level 0 (avoid)
window.onorientationchange = function(){};

// DOM Level 2
window.addEventListener('orientationchange', function(){}, false);
</pre>
<p><a href="http://www.iphonemicrosites.com/articles/6-tips-to-optimize-your-current-site-for-the-iphone/">Some websites</a> recommend using <code>orientationchange</code> to dynamically add an <code>orient</code> attribute on the <code>body</code> element and target the orientation with CSS selectors (<code>body[orient=landscape]</code>), <i>but this is in error</i>.  As it turns out, <code>orientationchange</code> is only fired AFTER the screen has been rotated (which also <a href="http://www.stubbornella.org/content/2009/03/27/reflows-repaints-css-performance-making-your-javascript-slow/">triggers a CSS reflow</a>), which means this attribute is updated later (after the reflow).  And unfortunately editing this <code>orient</code> attribute doesn&#8217;t trigger another CSS reflow.  The result?  When you rotate the device, these new CSS styles don&#8217;t get applied!</p>
<p>The fix is to add the orientation as a CSS class, which does trigger a CSS reflow.  So our code at this point will look something like this:</p>
<pre name="code" class="JScript">
(function(){
var init = function() {
  var updateOrientation = function() {
    var orientation = window.orientation;

    switch(orientation) {
      case 90: case -90:
        orientation = 'landscape';
      break;
      default:
        orientation = 'portrait';
    }

    // set the class on the HTML element (i.e. <html class="portrait">)
    document.body.parentNode.setAttribute('class', orientation);
  };

  // event triggered every 90 degrees of rotation
  window.addEventListener('orientationchange', updateOrientation, false);

  // initialize the orientation
  updateOrientation();
}

window.addEventListener('DOMContentLoaded', init, false);

})();
</pre>
<p>Now we can target elements like this in CSS:</p>
<pre name="code" class="CSS">
.portrait body div { width: 10%; }
.landscape body div { width: 15%; }
</pre>
<h3>With a little help from media queries</h3>
<p>You may have heard of <a href="https://developer.mozilla.org/en/css/media_queries">media queries</a> being used to target mobile devices (based on screen pixel width) or to <a href="http://www.bdoran.co.uk/2010/07/19/detecting-the-iphone4-and-resolution-with-javascript-or-php/">target the iPhone 4&#8242;s Retina display</a>, but you may not have known that you can also target screen orientation!</p>
<pre name="code" class="CSS">
@media all and (orientation: portrait) {
  body div { width: 10%; }
}

@media all and (orientation: landscape) {
  body div { width: 15%; }
}
</pre>
<p>The orientation media query is available on iOS 3.2+, Android 2.0+, and some other browsers.</p>
<p>This is a lot cleaner than the above JavaScript example in the sense that it&#8217;s pure CSS, and it&#8217;s part of the CSS that gets reflowed when the screen is rotated.</p>
<p>(Minor note: iOS 4 on the iPhone Simulator running 4.0.0 looks like it&#8217;s stuck in landscape orientation, but the media queries work correctly on my 3GS with 4.0.1)</p>
<h3>Fallback: when window.orientation and media queries aren&#8217;t available&#8230;</h3>
<p>If <code>window.orientation</code> isn&#8217;t available on a device, chances are the <code>orientationchange</code> event and media queries (for orientation) will also not be available.  Oh no, what do we do now?</p>
<p>Even though this isn&#8217;t an entirely foolproof method, we can dynamically measure the window width and height and guess orientation based on that:</p>
<pre name="code" class="JS">
(function(){
var HTMLNode = document.body.parentNode;
var updateOrientation = function() {
  // landscape when width is biggest, otherwise portrait
  var orientation = (window.innerWidth > window.innerHeight) ? 'landscape': 'portrait';

  // set the class on the HTML element (i.e. <html class="portrait">)
  HTMLNode.setAttribute('class', orientation);
}
var init = function() {
  // initialize the orientation
  updateOrientation();

  // update every 5 seconds
  setInterval(updateOrientation, 5000);
}
window.addEventListener('DOMContentLoaded', init, false);
})();
</pre>
<p>Ok, so it&#8217;s not pretty, but it seems to work.  The overhead in this fallback example is the fact that we have to use a polling technique (in this case every 5 seconds [5000 milliseconds]) to check for changes in orientation.</p>
<p>Note: there&#8217;s also the strong possibility that these browsers will not support the <code>DOMContentLoaded</code> event, but we&#8217;ll ignore that for the purposes of this article. (if you have problems, change <code>DOMContentLoaded</code> to <code>load</code>)</p>
<h3>Putting it all together</h3>
<p>Ok, so if you want the fallback example to work in addition to newer methods, unless you want to duplicate your CSS, then avoid using media queries to target orientation.  Instead we&#8217;ll rely on adding a class to the <code>html</code> tag (or the <code>body</code> tag if you prefer).</p>
<p>Once we put everything together, we get something that looks like this:</p>
<pre name="code" class="JScript">
(function(){
var supportsOrientation = (typeof window.orientation == 'number' &#038;&#038; typeof window.onorientationchange == 'object');
var HTMLNode = document.body.parentNode;
var updateOrientation = function() {
  // rewrite the function depending on what's supported
  if(supportsOrientation) {
    updateOrientation = function() {
      var orientation = window.orientation;

      switch(orientation) {
        case 90: case -90:
          orientation = 'landscape';
        break;
        default:
          orientation = 'portrait';
      }

      // set the class on the HTML element (i.e. <html class="portrait">)
      HTMLNode.setAttribute('class', orientation);
    }
  } else {
    updateOrientation = function() {
      // landscape when width is biggest, otherwise portrait
      var orientation = (window.innerWidth > window.innerHeight) ? 'landscape': 'portrait';

      // set the class on the HTML element (i.e. <html class="portrait">)
      HTMLNode.setAttribute('class', orientation);
    }
  }

  updateOrientation();
}
var init = function() {
  // initialize the orientation
  updateOrientation();

  if(supportsOrientation) {
    window.addEventListener('orientationchange', updateOrientation, false);
  } else {
    // fallback: update every 5 seconds
    setInterval(updateOrientation, 5000);
  }

}
window.addEventListener('DOMContentLoaded', init, false);
})();
</pre>
<p>Minified (540 bytes):</p>
<pre name="code" class="JScript">
(function(){var e=typeof window.orientation=="number"&#038;&#038;typeof window.onorientationchange=="object",f=document.body.parentNode;function c(){c=e?function(){var d=window.orientation;switch(d){case 90:case -90:d="landscape";break;default:d="portrait"}f.setAttribute("class",d)}:function(){f.setAttribute("class",window.innerWidth>window.innerHeight?"landscape":"portrait")};c()}window.addEventListener("DOMContentLoaded",function(){c();e?window.addEventListener("orientationchange",c,false):setInterval(c,5E3)},false)})();
</pre>
<h3>Conclusion</h3>
<p>And that&#8217;s it!  Now we can reliably target different screen orientations with some straightforward CSS:</p>
<pre name="code" class="CSS">
.portrait body div { width: 10%; }
.landscape body div { width: 15%; }
</pre>
<p>Again, in my experience I&#8217;ve used this to fix bugs.  But I&#8217;m sure you can find more creative uses for it!</p>
<h3>Related</h3>
<p><a href="http://www.nczonline.net/blog/2010/04/06/ipad-web-development-tips/">iPad web development tips (Nicholas C. Zakas)</a><br />
<a href="http://ajaxian.com/archives/iphone-windowonorientationchange-code">iPhone window.onorientationchange Code (Ajaxian)</a><br />
<a href="http://www.quirksmode.org/blog/archives/2010/04/the_orientation.html">The orientation media query (Quirksmode)</a></p>
<h3>More from the Mobile Web series:</h3>
<p><a href="http://davidbcalhoun.com/2010/viewport-metatag">Part 1: The viewport metatag</a><br />
<a href="http://davidbcalhoun.com/2010/the-mobile-developers-toolkit-mobile-web-part-2">Part 2: The mobile developer’s toolkit</a><br />
<a href="http://davidbcalhoun.com/2010/designing-buttons-that-dont-suck">Part 3: Designing buttons that don’t suck</a><br />
<a href="http://davidbcalhoun.com/2010/on-designing-a-mobile-webpage">Part 4: On designing a mobile webpage</a><br />
<a href="http://davidbcalhoun.com/2010/using-mobile-specific-html-css-javascript">Part 5: Using mobile-specific HTML, CSS, and JavaScript</a><br />
<a href="http://davidbcalhoun.com/2010/dealing-with-device-orientation">Part 6: Dealing with device orientation</a><br />
<a href="http://davidbcalhoun.com/2010/mobile-javascript-libraries-and-frameworks">Part 7: Mobile JavaScript libraries and frameworks</a></p>
]]></content:encoded>
			<wfw:commentRss>http://davidbcalhoun.com/2010/dealing-with-device-orientation/feed</wfw:commentRss>
		<slash:comments>17</slash:comments>
		</item>
		<item>
		<title>Using mobile-specific HTML, CSS, and JavaScript (Mobile web part 5)</title>
		<link>http://davidbcalhoun.com/2010/using-mobile-specific-html-css-javascript</link>
		<comments>http://davidbcalhoun.com/2010/using-mobile-specific-html-css-javascript#comments</comments>
		<pubDate>Wed, 30 Jun 2010 03:27:11 +0000</pubDate>
		<dc:creator>David</dc:creator>
				<category><![CDATA[mobile]]></category>
		<category><![CDATA[basejs]]></category>
		<category><![CDATA[blackberry.network]]></category>
		<category><![CDATA[blackberry.system]]></category>
		<category><![CDATA[capture api]]></category>
		<category><![CDATA[css]]></category>
		<category><![CDATA[gesture events]]></category>
		<category><![CDATA[html]]></category>
		<category><![CDATA[iui]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[jqtouch]]></category>
		<category><![CDATA[media queries]]></category>
		<category><![CDATA[mozorientation]]></category>
		<category><![CDATA[orientationchange]]></category>
		<category><![CDATA[pastrykit]]></category>
		<category><![CDATA[touch events]]></category>
		<category><![CDATA[webkit]]></category>
		<category><![CDATA[xui]]></category>

		<guid isPermaLink="false">http://davidbcalhoun.com/?p=317</guid>
		<description><![CDATA[(updated June 27, 2011) Mobile-specific HTML Viewport tag Use the viewport tag to properly fit the content to the screen: &#60;meta name=&#34;viewport&#34; content=&#34;width=device-width, initial-scale=1.0&#34;/&#62; Tel scheme (to initiate phone calls) &#60;a href=&#34;tel:18005555555&#34;&#62;Call us at 1-800-555-5555&#60;/a&#62; Sms scheme (to initiate text messages) &#60;a href=&#34;sms:18005555555&#34;&#62; &#60;a href=&#34;sms:18005555555,18005555556&#34;&#62; &#60;!-- multiple recipients --&#62; &#60;a href=&#34;sms:18005555555?body=Text%20goes%20here&#34;&#62; &#60;!-- predefined message body [...]]]></description>
			<content:encoded><![CDATA[<p><em>(updated June 27, 2011)</em></p>
<h3>Mobile-specific HTML</h3>
<h4>Viewport tag</h4>
<p>Use the <a href="http://davidbcalhoun.com/2010/viewport-metatag">viewport tag</a> to properly fit the content to the screen:</p>
<pre name="code" class="html">
&lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot;/&gt;
</pre>
<h4><a href="http://www.rfc-editor.org/rfc/rfc3966.txt">Tel scheme</a> (to initiate phone calls)</h4>
<pre name="code" class="html">
&lt;a href=&quot;tel:18005555555&quot;&gt;Call us at 1-800-555-5555&lt;/a&gt;
</pre>
<h4><a href="http://www.rfc-editor.org/rfc/rfc5724.txt">Sms scheme</a> (to initiate text messages)</h4>
<pre name="code" class="html">
&lt;a href=&quot;sms:18005555555&quot;&gt;
&lt;a href=&quot;sms:18005555555,18005555556&quot;&gt;              &lt;!-- multiple recipients --&gt;
&lt;a href=&quot;sms:18005555555?body=Text%20goes%20here&quot;&gt;  &lt;!-- predefined message body --&gt;
</pre>
<h4>Disable automatic telephone number linking</h4>
<pre name="code" class="html">
&lt;meta name=&quot;format-detection&quot; content=&quot;telephone=no&quot;&gt;
</pre>
<h4>iOS-specific HTML (some work on Android as well)</h4>
<p>You also have access to several <a href="http://developer.apple.com/library/safari/#documentation/appleapplications/reference/safariwebcontent/configuringwebapplications/configuringwebapplications.html">Apple-specific tags to use in your iOS applications (iPhone, iPad, and don&#8217;t forget the iPod Touch!)</a>.</p>
<pre name="code" class="html">
<!-- iOS 1.1.3+: this is the icon that's used when the user adds your app to the home screen -->
<!-- also works on Android! -->
&lt;link rel=&quot;apple-touch-icon&quot; href=&quot;icon.png&quot;/&gt;

<!-- iOS 2.0+: tell iOS not to apply any glare effects to the icon -->
&lt;link rel=&quot;apple-touch-icon-precomposed&quot; href=&quot;icon.png&quot;/&gt;

<!-- iOS 4.2+ icons for different resolutions -->
&lt;link rel=&quot;apple-touch-icon&quot; sizes=&quot;72x72&quot; href=&quot;touch-icon-ipad.png&quot; /&gt;
&lt;link rel=&quot;apple-touch-icon&quot; sizes=&quot;114x114&quot; href=&quot;touch-icon-iphone4.png&quot; /&gt;

<!-- iOS 3+: full-screen startup splash screen image (must be 320x460) -->
&lt;link rel=&quot;apple-touch-startup-image&quot; href=&quot;startup.png&quot;&gt;

<!-- enable full-screen mode (only when launched from home screen) -->
&lt;meta name=&quot;apple-mobile-web-app-capable&quot; content=&quot;yes&quot; /&gt;

<!-- controls the appearance of the status bar in full-screen mode -->
&lt;meta name=&quot;apple-mobile-web-app-status-bar-style&quot; content=&quot;black&quot; /&gt;
</pre>
<h4>Turn off autocorrect, autocomplete, and autocapitalize</h4>
<p>And also some handy attributes to turn off annoying autocorrect features:</p>
<pre name="code" class="html">
&lt;input autocorrect=&quot;off&quot; autocomplete=&quot;off&quot; autocapitalize=&quot;off&quot;&gt;
</pre>
<h3>Mobile-specific CSS</h3>
<h4>position:fixed and overflow:scroll</h4>
<p>Mobile browsers are now starting to support these basic CSS properties better.  Position:fixed will work on Android 2.2+ and iOS 5+.  Overflow:scroll works with one finger on iOS 5+.</p>
<p>Also, iOS 5 has additional CSS to give the native scrollbar and momentum/intertia to elements with overflow:scroll: <code>-webkit-overflow-scrolling: touch;</code></p>
<h4>Media queries</h4>
<p><a href="http://www.w3.org/TR/css3-mediaqueries/">Media queries</a> enable you to target specific features (screen width, orientation, resolution) within CSS itself.  Media queries themselves are actually quite old and are not mobile specific (they used to be popular for making a print-friendly version of webpages).</p>
<p>You can use them two ways: 1) inline in a CSS stylesheet or 2) as the &#8220;media&#8221; attribute in the link tag, which loads an external stylesheet.  The following is an example of inline CSS that&#8217;s applied only when the device is in portrait mode:</p>
<pre name="code" class="css">
@media all and (orientation: portrait) {
	body { }
	div { }
}
</pre>
<p>Here&#8217;s the same media query using the other method, which points to an external stylesheet (not recommended):</p>
<pre name="code" class="html">
&lt;link rel=&quot;stylesheet&quot; media=&quot;all and (orientation: portrait)&quot; href=&quot;portrait.css&quot; /&gt;
</pre>
<p>This is not recommended because it creates an additional HTTP request (bad for performance).  Also, in the case of screen orientation, the separate CSS stylesheet is NOT downloaded when the screen is rotated.</p>
<p>Here&#8217;s a few examples of using inline CSS:</p>
<pre name="code" class="css">
// target small screens (mobile devices or small desktop windows)
@media only screen and (max-width: 480px) {
  /* CSS goes here */
}

/* high resolution screens */
@media (-webkit-min-device-pixel-ratio: 2),
             (min--moz-device-pixel-ratio: 2),
             (min-resolution: 300dpi) {
  header { background-image: url(header-highres.png); }
}

/* low resolution screens */
@media (-webkit-max-device-pixel-ratio: 1.5),
             (max--moz-device-pixel-ratio: 1.5),
             (max-resolution: 299dpi) {
  header { background-image: url(header-lowres.png); }
}
</pre>
<p>Read more: <a href="https://developer.mozilla.org/en/css/media_queries">Media queries (Mozilla Developer Center)</a></p>
<h4>Miscellaneous CSS</h4>
<p>-webkit-tap-highlight-color (iOS): override the semitransparent color overlay when a user clicks a link or clickable element.  To completely disable it, set the value to &#8216;transparent&#8217; or &#8216;rgba(0,0,0,0)&#8217;</p>
<p>-webkit-user-select: none; &#8211; prevent the user from selecting text (also works on desktop WebKit)</p>
<p>-webkit-touch-callout: none; &#8211; prevent the callout toolbar from appearing when a user touches and holds an element such as an anchor tag.</p>
<h3>Mobile-specific JavaScript</h3>
<h4>window.scrollTo(0,0);</h4>
<p>This hides the address bar and takes advantage of the entire device screen.  You&#8217;ll have to set this in a timeout and make sure to get the timing right.  See <a href="http://remysharp.com/2010/08/05/doing-it-right-skipping-the-iphone-url-bar/">Remy Sharp&#8217;s post</a> for more details.</p>
<h4>window.matchMedia()</h4>
<p>(iOS 5+) Again, just as CSS media queries aren&#8217;t specific to mobile, they do come in especially useful for mobile, so it&#8217;s worth mentioning their JavaScript counterpart.  window.matchMedia() is a JavaScript-based version of media queries.  You can use <a href="https://github.com/scottjehl/Respond">respond.js</a> as a polyfill for devices that don&#8217;t support this functionality natively.</p>
<h4>navigator.connection</h4>
<p>(Android 2.2+) Determine if the phone is running on WiFi, 3G, etc.  Example:
<pre name="code" class="JScript">
if (navigator.connection.type==navigator.connection.WIFI) {
  // code for WiFi connections (high-bandwidth)
}
</pre>
<h4>window.devicePixelRatio</h4>
<p>Determine screen resolution (analogue to the CSS media query).  (iPhone 4 has the value 2, while Nexus One has the value 1.5).</p>
<h4>window.navigator.onLine</h4>
<p>Not strictly mobile, but helpful for apps to determine if they&#8217;re being run offline.</p>
<h4>window.navigator.standalone</h4>
<p>(iOS 2.1+): determine if it&#8217;s running in full-screen mode</p>
<h4>Touch and gesture events</h4>
<p><a href="http://developer.apple.com/safari/library/documentation/appleapplications/reference/safariwebcontent/handlingevents/handlingevents.html">touch events (iOS, Android 2.2+)</a>: touchstart, touchmove, touchend, touchcancel</p>
<p><a href="http://developer.apple.com/safari/library/documentation/internetweb/conceptual/safarivisualeffectsprogguide/InteractiveVisualEffects/InteractiveVisualEffects.html">gesture events (Apple only, iOS 2+)</a>: gesturestart, gesturechange, gesturend give access to predefined gestures (rotation, scale, position)</p>
<h4>Screen orientation (every 90 degrees)</h4>
<p><a href="http://ajaxian.com/archives/iphone-windowonorientationchange-code">orientationchange event</a>: triggered every 90 degrees of rotation (portrait and landscape modes).  The current orientation is available through window.orientation</p>
<h4>Device orientation (more fine-grained)</h4>
<p>The <a href="http://frontendstuff.com/javascript/examples/deviceorientation.html">deviceorientation event</a> will fire very frequently, and gives more fine-grained information about the device&#8217;s orientation in three dimensions.<br />
<a href="https://developer.mozilla.org/en/Detecting_device_orientation">MozOrientation</a> (or onmozorientation?) (Fennec/Firefox Mobile, Firefox 3.5+): also not strictly mobile.  Gives access to the device&#8217;s accelerometer (x-y-z orientation data), updated periodically.  Works on Android phones running Mobile Firefox.  On the desktop this works with laptops such as Thinkpads and MacBooks.</p>
<h4>devicemotion (shake gestures, etc.)</h4>
<p><a href="http://frontendstuff.com/javascript/examples/devicemotion.html">devicemotion</a> fires when the user shakes or moves their device.  Devicemotion taps into the accelerometer, which is fires off when the device accelerates.  Contrast this with the deviceorientation event, which taps into the device&#8217;s gyroscope (if it has one), which only measures the 3D angle orientation, even when the device is at rest.</p>
<h4>Media capture API</h4>
<p>While iOS is still lacking basic file inputs, Android is forging ahead, giving developers fine-grained control over content users can upload.</p>
<pre name="code" class="html">
&lt;!-- regular file upload (Android 2.2+, NO iOS) --&gt;
&lt;input type=&quot;file&quot;&gt;&lt;/input&gt;

&lt;!-- opens directly to the camera (Android 3.0+) --&gt;
&lt;input type=&quot;file&quot; accept=&quot;image/*;capture=camera&quot;&gt;&lt;/input&gt;

&lt;!-- opens directly to the camera in video mode (Android 3.0+) --&gt;
&lt;input type=&quot;file&quot; accept=&quot;video/*;capture=camcorder&quot;&gt;&lt;/input&gt;

&lt;!-- opens directly to the audio recorder (Android 3.0+) --&gt;
&lt;input type=&quot;file&quot; accept=&quot;audio/*;capture=microphone&quot;&gt;&lt;/input&gt;
</pre>
<h4>BlackBerry specific</h4>
<p>If you&#8217;re developing for a BlackBerry Widget, you have access to proprietary information through the <a href="http://www.blackberry.com/developers/docs/widgetapi/Summary_system.html">blackberry object</a> (which gives access to useful information such as blackberry.network [returns values such as CDMA and Wi-Fi] and blackberry.system).</p>
<p>You also have the option to use <a href="http://phonegap.com/">PhoneGap</a>, which augments JavaScript and gives you access to more phone features that native apps would have access to.</p>
<h3>Use a mobile-optimized JavaScript library</h3>
<p>I&#8217;ve created <a href="http://davidbcalhoun.com/2010/mobile-javascript-libraries-and-frameworks">a separate entry for the available mobile libraries and frameworks</a>.</p>
<p>Because smartphone browsers are standards-based, the aim of a JavaScript library on mobile is less towards API normalization and more towards providing an actual UI framework, usually to emulate the feel of native apps (and to provide easier workarounds to <a href="http://doctyper.com/archives/200808/fixed-positioning-on-mobile-safari/">lack of access to position:fixed</a>).  We&#8217;ve seen a few libraries released that emulate the iPhone UI, and in the future we might see libraries emulating the Android UI, as well as entirely new UIs.</p>
<p>There&#8217;s also a bit to be said about simply loading full desktop JavaScript libraries into mobile clients.  In my opinion this doesn&#8217;t particularly make sense, especially in a world where latency and bandwidth are so much more of a concern.  It doesn&#8217;t make sense to force the user wait longer and download code that&#8217;s ultimately useless to them (hacks for desktop browsers such as IE 6, etc).</p>
<h3>Take advantage of new stuff!</h3>
<p>While not specific to mobile, there&#8217;s a lot of new stuff in general that you can use.  If you limit yourself to the top smartphones (iPhone, Android, and maybe webOS), compared to the desktop you immediately have access to an even wider array of new stuff, especially many Webkit proprietary features, since most of these top smartphones have browsers based on Webkit.</p>
<p>-HTML: new tags (<a href="http://diveintohtml5.org/">HTML5</a> (I&#8217;m sure you&#8217;ve heard of it by now…))<br />
-CSS: <a href="http://webkit.org/blog/130/css-transforms/">2d transforms</a>, <a href="http://webkit.org/blog/386/3d-transforms/">3d transforms</a>, animation, <a href="http://border-radius.com/">border radius</a>, <a href="https://developer.mozilla.org/en/css/@font-face">custom fonts with @font-face</a>, etc.<br />
-JavaScript: <a href="http://ejohn.org/blog/ecmascript-5-strict-mode-json-and-more/">strict mode</a>, <a href="https://developer.mozilla.org/en/Core_JavaScript_1.5_Guide/Core_Language_Features#Constants">constants</a>, <a href="http://davidbcalhoun.com/2009/javascript-tidbit-block-scope-with-let">block scope</a>, <a href="https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Date">Date.now()</a>, etc.</p>
<h3>Slides</h3>
<div style="width:425px" id="__ss_7424222"> <strong style="display:block;margin:12px 0 4px"><a href="http://www.slideshare.net/franksvalli/mobile-html-css-and-javascript" title="Mobile HTML, CSS, and JavaScript">Mobile HTML, CSS, and JavaScript</a></strong> <iframe src="http://www.slideshare.net/slideshow/embed_code/7424222" width="425" height="355" frameborder="0" marginwidth="0" marginheight="0" scrolling="no"></iframe>
<div style="padding:5px 0 12px"> View more <a href="http://www.slideshare.net/">presentations</a> from <a href="http://www.slideshare.net/franksvalli">franksvalli</a> </div>
</p></div>
<h3>More from the Mobile Web series:</h3>
<p><a href="http://davidbcalhoun.com/2010/viewport-metatag">Part 1: The viewport metatag</a><br />
<a href="http://davidbcalhoun.com/2010/the-mobile-developers-toolkit-mobile-web-part-2">Part 2: The mobile developer’s toolkit</a><br />
<a href="http://davidbcalhoun.com/2010/designing-buttons-that-dont-suck">Part 3: Designing buttons that don’t suck</a><br />
<a href="http://davidbcalhoun.com/2010/on-designing-a-mobile-webpage">Part 4: On designing a mobile webpage</a><br />
<a href="http://davidbcalhoun.com/2010/using-mobile-specific-html-css-javascript">Part 5: Using mobile-specific HTML, CSS, and JavaScript</a><br />
<a href="http://davidbcalhoun.com/2010/dealing-with-device-orientation">Part 6: Dealing with device orientation</a><br />
<a href="http://davidbcalhoun.com/2010/mobile-javascript-libraries-and-frameworks">Part 7: Mobile JavaScript libraries and frameworks</a></p>
]]></content:encoded>
			<wfw:commentRss>http://davidbcalhoun.com/2010/using-mobile-specific-html-css-javascript/feed</wfw:commentRss>
		<slash:comments>37</slash:comments>
		</item>
		<item>
		<title>iPhone 4 SunSpider test results (22% faster than iPhone 3GS)</title>
		<link>http://davidbcalhoun.com/2010/iphone-4-sunspider-test-results</link>
		<comments>http://davidbcalhoun.com/2010/iphone-4-sunspider-test-results#comments</comments>
		<pubDate>Fri, 25 Jun 2010 16:57:53 +0000</pubDate>
		<dc:creator>David</dc:creator>
				<category><![CDATA[mobile]]></category>
		<category><![CDATA[iphone]]></category>
		<category><![CDATA[iphone 4]]></category>
		<category><![CDATA[performance]]></category>
		<category><![CDATA[sunspider]]></category>

		<guid isPermaLink="false">http://davidbcalhoun.com/?p=312</guid>
		<description><![CDATA[============================================ RESULTS (means and 95% confidence intervals) -------------------------------------------- Total: 10669.4ms +/- 1.0% -------------------------------------------- 3d: 1471.5ms +/- 2.1% cube: 428.7ms +/- 2.6% morph: 584.3ms +/- 4.7% raytrace: 458.5ms +/- 0.6% access: 1476.7ms +/- 1.3% binary-trees: 151.6ms +/- 1.3% fannkuch: 664.0ms +/- 0.1% nbody: 397.9ms +/- 2.1% nsieve: 263.2ms +/- 6.3% bitops: 947.2ms +/- 2.1% 3bit-bits-in-byte: 195.7ms [...]]]></description>
			<content:encoded><![CDATA[<pre>
============================================
RESULTS (means and 95% confidence intervals)
--------------------------------------------
Total:                 10669.4ms +/- 1.0%
--------------------------------------------

  3d:                   1471.5ms +/- 2.1%
    cube:                428.7ms +/- 2.6%
    morph:               584.3ms +/- 4.7%
    raytrace:            458.5ms +/- 0.6%

  access:               1476.7ms +/- 1.3%
    binary-trees:        151.6ms +/- 1.3%
    fannkuch:            664.0ms +/- 0.1%
    nbody:               397.9ms +/- 2.1%
    nsieve:              263.2ms +/- 6.3%

  bitops:                947.2ms +/- 2.1%
    3bit-bits-in-byte:   195.7ms +/- 2.0%
    bits-in-byte:        206.1ms +/- 1.0%
    bitwise-and:         179.7ms +/- 1.1%
    nsieve-bits:         365.7ms +/- 3.9%

  controlflow:           169.5ms +/- 8.0%
    recursive:           169.5ms +/- 8.0%

  crypto:                668.7ms +/- 1.0%
    aes:                 307.0ms +/- 1.4%
    md5:                 181.1ms +/- 3.1%
    sha1:                180.6ms +/- 1.0%

  date:                  838.4ms +/- 4.6%
    format-tofte:        420.9ms +/- 7.4%
    format-xparb:        417.5ms +/- 2.8%

  math:                 1161.9ms +/- 1.0%
    cordic:              424.9ms +/- 0.5%
    partial-sums:        385.1ms +/- 0.3%
    spectral-norm:       351.9ms +/- 2.9%

  regexp:               1479.3ms +/- 0.1%
    dna:                1479.3ms +/- 0.1%

  string:               2456.2ms +/- 0.9%
    base64:              347.6ms +/- 3.1%
    fasta:               408.1ms +/- 6.7%
    tagcloud:            447.7ms +/- 0.6%
    unpack-code:         797.8ms +/- 0.4%
    validate-input:      455.0ms +/- 0.4%
</pre>
<h3>Summary</h3>
<p>Thanks to my coworker for lending me his phone for a few minutes (he waited in line for 9 hours yesterday when it first went on sale!).</p>
<p>This is quite an improvement over the <a href="http://davidbcalhoun.com/2010/sunspider-ios-3-1-3-versus-ios-4-gm">iPhone 3GS running iOS4, which ran the SunSpider test in 13787ms</a>.  The iPhone 4 ran the same test in 10669ms, which makes it ~22% faster head-to-head.</p>
<h3>Processors</h3>
<p>The iPhone 3GS has a Samsung S5PC100 ARM Cortex-A8[5] 833 MHz (underclocked to 600 MHz), while the iPhone 4 has an Apple A4 1GHz (likely underclocked to an unknown speed).</p>
]]></content:encoded>
			<wfw:commentRss>http://davidbcalhoun.com/2010/iphone-4-sunspider-test-results/feed</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>How to install obsolete Android Virtual Devices (AVDs)</title>
		<link>http://davidbcalhoun.com/2010/how-to-install-obsolete-android-virtual-devices-avds</link>
		<comments>http://davidbcalhoun.com/2010/how-to-install-obsolete-android-virtual-devices-avds#comments</comments>
		<pubDate>Thu, 10 Jun 2010 02:00:38 +0000</pubDate>
		<dc:creator>David</dc:creator>
				<category><![CDATA[mobile]]></category>
		<category><![CDATA[android]]></category>
		<category><![CDATA[avd]]></category>
		<category><![CDATA[emulator]]></category>

		<guid isPermaLink="false">http://davidbcalhoun.com/?p=275</guid>
		<description><![CDATA[Apparently it&#8217;s no longer possible to easily download Android versions 2.0 and 2.0.1 from the AVD Manager. I noticed this problem when I got a new machine and had to install everything from scratch. In the future I suspect even more AVDs will be made obsolete, so this solution also applies to them. Why would [...]]]></description>
			<content:encoded><![CDATA[<p>Apparently it&#8217;s no longer possible to easily download Android versions 2.0 and 2.0.1 from the AVD Manager.   I noticed this problem when I got a new machine and had to install everything from scratch.  In the future I suspect even more AVDs will be made obsolete, so this solution also applies to them.</p>
<p>Why would you want to install obsolete AVDs?  In my case it&#8217;s a matter of research: I simply want to see the progress of features being added to its browser, and track those changes over time.</p>
<h3>Step 1: Manually download and inspect repository.xml</h3>
<p>When updating from &#8220;Available Packages&#8221; there&#8217;s a little one-line error saying &#8220;Some packages were found but are not compatible updates.&#8221;</p>
<p>Ok, so let&#8217;s check out the XML for ourselves to see if we can find anything.  So point your browser to <a href="https://dl-ssl.google.com/android/repository/repository.xml">https://dl-ssl.google.com/android/repository/repository.xml</a> (to see the XML, right click to view the page source if you&#8217;re using a Webkit-based browser).</p>
<p>Search for the AVD version you want.  In this case we want 2.0 and 2.0.1, so a simple search find the relevant blocks of code.  And we also find the XML tag that&#8217;s the cause of our troubles, which prevents us from easily getting the AVDs:</p>
<pre name="code" class="xml">
&lt;sdk:obsolete /&gt;
</pre>
<h3>Step 2: Get the AVDs!</h3>
<p>At this point you could do two things, either save repository.xml to your computer and remove these &#8220;obsolete&#8221; tags (then add the XML to your AVD Manager by clicking &#8220;Add Add-on Site&#8230;&#8221;), or simply find the path to the AVD and download it manually.</p>
<p>The second option is to simply manually download the paths, which are easy to find in the XML and are listed here for your convenience:<br />
<a href="https://dl-ssl.google.com/android/repository/android-2.0_r01-linux.zip">Android 2.0 AVD (Linux)</a><br />
<a href="https://dl-ssl.google.com/android/repository/android-2.0_r01-macosx.zip">Android 2.0 AVD (Mac OSX)</a><br />
<a href="https://dl-ssl.google.com/android/repository/android-2.0_r01-windows.zip">Android 2.0 AVD (Windows)</a></p>
<p><a href="https://dl-ssl.google.com/android/repository/android-2.0.1_r01-linux.zip">Android 2.0.1 AVD (Linux)</a><br />
<a href="https://dl-ssl.google.com/android/repository/android-2.0.1_r01-macosx.zip">Android 2.0.1 AVD (Mac OSX)</a><br />
<a href="https://dl-ssl.google.com/android/repository/android-2.0.1_r01-windows.zip">Android 2.0.1 AVD (Windows)</a></p>
<h3>Step 3: Install!</h3>
<p>Create directories under your Android SDK installation&#8217;s &#8220;platforms&#8221; folder.  In this case we have 2.0 (API level 5) and 2.0.1 (API level 6), so I created these folders: android-5 and android-6.  Now just unzip the contents into these folders.</p>
<p>Start up the AVD Manager and click on &#8220;Installed Packages&#8221;.  If you don&#8217;t see your new (obsolete) packages you just installed, hit the Refresh button and you should see them.</p>
<p>Now you can create new AVDs with these obsolete packages!</p>
]]></content:encoded>
			<wfw:commentRss>http://davidbcalhoun.com/2010/how-to-install-obsolete-android-virtual-devices-avds/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

