Mobile WebKit Optimizations & Tools
11 August 2011 · Estimated reading time: 7 minutes
Last night I presented at the Mt View JavaScript Meetup (along with Glan). The following are my slide notes along with links to relevant resources. Get on the bus, ’cuz we’re goin’ to school!
At the Meetup, I showed my slides in Google Chrome using my SlideKit slideshow framework. Because that only runs in WebKit browsers, I’ve since posted them to SlideShare and embedded them below for your viewing pleasure.
- My team at Tapulous builds web views that behave as close as possible to native iOS (and Android) screens.
- Tapulous (part of Disney Mobile) has released a string of #1 games in the 8 months I’ve worked there, including…
- Tap Tap Revenge 4
- Born This Way Revenge for Lady Gaga
- Tap Tap Glee for the FOX TV show
- ClubWorld, our first foray into tycoon gaming
- Cars 2 in collaboration with Pixar
- The optimizations I covered, some of them apply on the open web, some apply to mobile environments in general, and some are specific to mobile WebKit
- On mobile, latency can be up to 10x greater (which is really worser) than on the desktop web. So, reducing the number of requests you make (and the number of hostnames you access in those requests, a point I neglected to mention in my talk) is über-important.
- Rather than linking to multiple CSS or JS files, contatentate them. Also, consider inlining rather than linking to these assets.
- Rather than linking to a bunch of small images, combine them into 1 image and use
background-position
to show the part you need. - In some cases, it can actually be advantageous to base64 and inline images (and other binary assets such as fonts) into your CSS or
img
tags using data URLs.
- It should be self-evident that it’s slower to send more bytes. Additionally, many users on mobile still have to deal with bandwidth caps (as do users in some parts of the world even on “broadband”, but that’s another story). So, yeah…send fewer bytes.
- The size of text components can be reduced on average by 70% by gzipping them. Most modern web servers can handle this no problem. You may already be doing it.
- Minifying CSS and JS is the process of stripping out unnecessary whitespace and comments from these files. Obfuscation is the process of reducing the length of tokens in JavaScript where possible. We use UglifyJS on our JS and YUI Compressor on our CSS. This is usually a big win.
- Using the right compression method for different types of images can save loads of bytes (as can persuading your designers to use a higher compression setting than they would otherwise!).
- There’s no sense in sending cookies along with static assets. Most CDNs are set up not to send cookies.
- One of the things I learned from Paul Irish at Texas JavaScript was that you can leave out a surprisingly high number of HTML tags from your documents and the browser will just fill them in for you. It may not save a huge amount of data, but, hey, if it’s good enough for Google, it’s good enough for me.
- Probably the biggest win in the mobile optimization game is not to hit the network if you don’t have to. Luckily, we have several caching techniques we can use.
- The “right” way to do caching on mobile WebKit is to use HTML5 cache manifests. Unfortunately, they’re a bit tricky to work with. This Dive into HTML5 article does a good job of providing examples of working code as well as explaining the pitfalls.
- Another tool at your disposal is localStorage. The API couldn’t be simpler. There’s a 5MB limit (without the user being alerted) and you can only store strings, but it’s a great way to cache, e.g., Ajax responses or JavaScript templates.
- In Tap Tap Revenge 4, we implemented a scheme that allowed us to cache pages and page fragments inside the app bundle. This requires coordination with the native host app, but again can be a way to avoid hitting the network if implemented correctly.
- A technique we’re investigating for future apps is to use custom URL scheme commands to request binary assets from within the app bundle. Something like
<img src="myapp://binaryasset/someimage.jpg">
- One of the nicest things about working in mobile WebKit all day is all of the things CSS3 allows us to do that were way harder just a couple of years ago.
- Most web developers are familiar with jQuery’s animate method. Before jQuery, I used to lean heavily on Bernie Sumption’s Animator lib. In 2006, it was ahead of its time. But, JavaScript is single-threaded and gated by the CPU. Now, we get to write some CSS and let the browser hardware accelerate the transforms, transitions, and animations.
- WebKit (and other modern browsers) also allow us to use a few lines of CSS to generate complex images such as gradients. These can save 100s of KBs. Some excellent gradient generators are popping up. You might be amazed at what is possible.
- A cool and underutilized technique you can use is CSS-only 9-slice borders. Your designers will thank you.
- It was a JavaScript Meetup, so I had to say a few words about the world’s most popular programming language.
- Touchscreen devices give us a new set of events for detecting user interactions. Touch events have some differences from more traditional mouse events, but the effort to learn how they work will pay off in a more native feeling experience.
- Profligate use of JavaScript closures can use a big chunk of a device’s meager RAM. Closures are an important technique, but if you make extensive use of them you may want to keep an eye on your memory consumption.
- Some JavaScript libraries (including our own internal stuff until recently!) execute code whether it’s needed or not. If at all possible, load your nicely concatenated JavaScript blob, but only run the code that’s strictly needed. E.g., you may include constructors for a bunch of objects, but only instantiate the ones you need for that page.
- 1000s of person hours have been put into open source JavaScript libraries. The developers have encountered and, in many cases, fixed or worked around countless bugs. Why wouldn’t you leverage their work?
- Zepto is a lightweight, WebKit-specific clone of jQuery. It weighs in at about 5KB and offers some of the familiar APIs as well as chaining.
- jQTouch is a jQuery plug-in that gives you the ability to create simple mobile apps quickly and easily. In a couple of our apps, we use a version of jQTouch we modified to work with Zepto.
- iScroll works around the lack of support for
position:fixed
in iOS versions of WebKit. It gives you the ability to designate scrolling regions in your pages that behave pretty darn close to native scrolling. - We are currently evaluating underscore.js and backbone.js for organizing our client-side code. Underscore is really a utility library, but a good one. Backbone provides an MVC structure to JS apps.
- You can get pretty far by building your pages in desktop Safari (or Chrome), but there is nothing like working on the device for being confident your code will behave as you expect. We find these tools indispensible for working in the relatively opaque environment of mobile Safari.
- Charles Proxy allows you to route traffic from your device through your desktop machine, allowing you to inspect requests and responses.
- Weinre is a remote debugging tool that lets you attach a debugging session to WebKit on your iOS, Android, or webOS device.
- Follow me on Twitter or email me with any questions!