Topics

  • Introduction to Toons
  • Why Web app
  • Web app challenges
  • Memory saving & performance tricks

First six weeks: over 150M Toons views

Toons are available on multiple platforms

  • Angry Birds games: web + native, hybrid app
  • Samsung SmartTV: web app
  • + Other distribution channels
  • This talk is about the iOS/Android web app

Why Web app instead of fully native?

  • Able to develop outside the game update cycle
  • Does not increase the file size of game install packages
  • Still able to use components from game
  • "Easy" to port to other platforms

What do we know (Android & iOS)

  • User's device most likely has a touch screen
  • WebKit based browsers
  • Browsers have decent HTML5/JS/CSS3 support
  • Game provides platform info (OS, OS version, resolution, etc.)

Frontend libraries used for the app

  • Backbone
  • Lo-Dash
  • Zepto
  • Rewritten version of SwipeView

Web app challenges

Biggest challenges

  • Limited memory (runs on top of a game, image heavy UI)
  • Web browser performance on Android
  • Bugs/fragmentation on Android
  • Scaling the UI to different screens
  • Limited connections speeds (many users have really slow connections)

Challenges - Android browser performance

Challenges - Scaling UI for different screen sizes

  • Fullscreen UI, somewhat flexible to both directions
  • No vector graphics: Android versions less than 3 do not support SVG
  • Images can't really be much larger than what fits the resolution (or memory runs out)
  • No media queries (MQs get bloated really fast with this kind of layout)

A resolution selector figures out the best resolution for the device

  • With a direct match returns assets for matching resolution
  • If not a direct match, figures out if minimum content width and height can fit
  • If content does not fit drops down to a lower resolution
  • Not a perfect solution, but always tries to get something to fit the screen

Memory saving & performace tricks

Mobile web app performance tricks

  • Show the UI ASAP (before content is fully loaded)
  • Minimize nr. of total HTTP requests
  • Preload intelligently
  • Keep nr. of AJAX reqs for your JSON data to minimum
  • Cache as much as possible
  • Try to reuse your assets and elements

Caching the web app

  • HTML5 localStorage not usable for us, increases memory usage on iOS
  • HTML5 App cache would require the UI to reload when assets are updated
  • We use long caching headers + filenames with a hash to allow cache to be purged
  • On Android persistent caching works ok, iOS needed some work

Caching: NSURLCache

(default cache for iOS WebView)

  • No disk caching in iOS 4 (only memory caching).
  • Disk caching capability after iOS 5, but iOS 5 doesn't persistently cache HTTPS responses
  • After iOS 6 persistent HTTPS caching is supported

Caching: NSURLCache

(default cache for iOS WebView)

Since all resources (html, js, images, etc) are served from HTTPS, we have implemented custom WebView caching based on iOS' URL loading system for iOS 5 and lower.

Speedy infinite scrolling: Reuse DOM nodes

  • Infinite scrollable list: only 15 "movie poster" + 5 container elements are needed.
  • Create elements once, move around with CSS transform: translate(x, y)
  • Avoid doing changes when user is scrolling
  • When user stops scrolling: unload and fill elements with new content.

Decrease total file size: How we save additional bytes

We:

  • Configure Gzipping for text based assests
  • Minify JS with Google Closure Compiler
  • Use Pngquant to convert PNGs to 8-bit
  • Images are big, replace with CSS3, @font-face, etc.

Decrease total file size: Reuse images

Only 1 curtain & half of the bg gets loaded

transform: scaleX(-1);

Those images are actually just flipped with CSS

Decrease total file size: Strip unused font characters

Decrease total file size: Modular JS libraries,
include only the modules you need

Lo-Dash

        $ npm install lodash -g
        $ lodash backbone mobile
      

Zepto

        $ git clone https://github.com/madrobby/zepto.git
        $ cd zepto
        $ npm install
        $ MODULES="zepto event ajax" ./make dist
      

Memory saving tricks

Images take a lot of memory, so:

  • If possible, use CSS3 & web fonts instead of images
  • Keep only currently visible images loaded
  • Split spritesheet images based on what is shown and hidden
  • Use non-retina images for high dpi devices with limited RAM

Memory: keep only visible images loaded

  • Middle page (3 images)
  • Pages on the sides (6 images)
  • First and fifth page (2 images)
  • = Only maximum of 11 images need to be loaded

Memory: unload images for infinite scrolling

 

Use an empty GIF image (base64 encoded DataURI) to force image unloading when the image is no longer needed:

 

        img.src = "data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==";
      

Thanks.