Slide 1

Slide 1 text

Optimizing JavaScript Runtime Performance for Touch Stephen Woods @ysaw

Slide 2

Slide 2 text

Native-Like Experience

Slide 3

Slide 3 text

Hardware Core OS Core Services Media Cocoa Touch

Slide 4

Slide 4 text

Hardware Core OS Core Services Media Cocoa Touch WebKit JavaScript Runtime WebCore

Slide 5

Slide 5 text

The Mobile Web is Slow

Slide 6

Slide 6 text

What Happens at runtime? • Fetch, format and Display Data • Handle UI Events • Move Pixels

Slide 7

Slide 7 text

Fetching Data

Slide 8

Slide 8 text

No content

Slide 9

Slide 9 text

No content

Slide 10

Slide 10 text

Caching: The cause of, and solution to, all of life's problems

Slide 11

Slide 11 text

$.get('data.json',  dataCallback);

Slide 12

Slide 12 text

$.get('/data.json',  dataCallback); myDAL.getData('key',  callback);

Slide 13

Slide 13 text

getData  =  function(key,  callback)  {    if(cache[key])  return  cache[key];    $.get('/data.json',  function(data){        cache[key]  =  data;        callback(data);    } } myDAL.getData('key',  callback);

Slide 14

Slide 14 text

window.localStorage['cache']  =           JSON.stringify(cache);

Slide 15

Slide 15 text

TTL Writes Invalidate Cache

Slide 16

Slide 16 text

Eviction www.flickr.com/photos/75397401@N02/ 5mbs of localStorage Strings stored as UTF-16 Characters Maximum Storage space: 2.5million Characters

Slide 17

Slide 17 text

Least Recently Used

Slide 18

Slide 18 text

No content

Slide 19

Slide 19 text

No content

Slide 20

Slide 20 text

No content

Slide 21

Slide 21 text

No content

Slide 22

Slide 22 text

No content

Slide 23

Slide 23 text

No content

Slide 24

Slide 24 text

Computing the size of the Cache. JSON.stringify(localStorage).length

Slide 25

Slide 25 text

Handling Events

Slide 26

Slide 26 text

Event handling is a conversation

Slide 27

Slide 27 text

If a gesture is in progress, the UI must be in motion.

Slide 28

Slide 28 text

Moving Pixels

Slide 29

Slide 29 text

30fps = 33.3ms Per Frame 60fps = 16.6ms Per Frame

Slide 30

Slide 30 text

No content

Slide 31

Slide 31 text

Write-Only DOM

Slide 32

Slide 32 text

getOffsetHeight : 74% slower than get className

Slide 33

Slide 33 text

If you can, cache the value, not the node

Slide 34

Slide 34 text

No content

Slide 35

Slide 35 text

No content

Slide 36

Slide 36 text

var  offsetCache  =  {}; function  getOffsetHeight(id)  {        if(offsetCache[id])  {                return  offsetCache[node.id];        }  else  {                offsetCache[id]  =                          document.getElementById(id).offsetHeight        } }

Slide 37

Slide 37 text

this.nodePositionMap[thisId]  =  {    top:  thisNode.getY(),    height:  thisNode.get('offsetHeight'),    defer:photoList[i].defer  ?  {img_url:  'bar'}:  false };

Slide 38

Slide 38 text

No content

Slide 39

Slide 39 text

background-­‐image:  'foo.jpg'; background-­‐size:  100%; transform:  translate3d(10,10,1);

Slide 40

Slide 40 text

No content

Slide 41

Slide 41 text

No content

Slide 42

Slide 42 text

User feedback comes first

Slide 43

Slide 43 text

isSwiping = 1;

Slide 44

Slide 44 text

function  handleXHR(resp)  {    if(isSwiping)  {        setTimeout(function(){                handleXHR(resp);        },20);    }    processData(desp); }

Slide 45

Slide 45 text

No content

Slide 46

Slide 46 text

• Load image ~ 300ms (async) • Find Faces ~ 100ms (sync) • Compute Entropy Crop ~ 30ms (sync) • Smooth Animation (sync)

Slide 47

Slide 47 text

Run Animation in a Separate Thread

Slide 48

Slide 48 text

slide1.style.transition  =  transitionDuration  +                                                      's  transform  ease-­‐out'; slide1.style.transform  =  computedEndFrame;

Slide 49

Slide 49 text

Run Slow Code in a Worker*

Slide 50

Slide 50 text

Run Slow Code in a Worker* *except on Android Browser

Slide 51

Slide 51 text

worker  =  new  Worker('/smart-­‐crop-­‐worker.js');

Slide 52

Slide 52 text

UI Thread Handles Events and Orchestration

Slide 53

Slide 53 text

• Cache data where possible • Update the UI on events, use transforms when possible • Multitask when you can, both with threads and yeilding

Slide 54

Slide 54 text

flickr.com/photos/39747297@N05/5230479916/ flickr.com/photos/pandameixiang/6784480227/ flickr.com/photos/ryfter/5196109310/ flickr.com/photos/howvin/4054392601/ flickr.com/photos/fdrlibrary/ @ysaw stephenwoods.net touch-interfaces.com flickr.jobs