Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Optimizing JavaScript Runtime Performance for Touch - Velocity 2013

Optimizing JavaScript Runtime Performance for Touch - Velocity 2013

Stephen Woods

June 19, 2013
Tweet

More Decks by Stephen Woods

Other Decks in Technology

Transcript

  1. Optimizing JavaScript Runtime
    Performance for Touch
    Stephen Woods
    @ysaw

    View full-size slide

  2. Native-Like Experience

    View full-size slide

  3. Hardware
    Core OS
    Core Services
    Media
    Cocoa Touch

    View full-size slide

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

    View full-size slide

  5. The Mobile Web is Slow

    View full-size slide

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

    View full-size slide

  7. Fetching Data

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  13. TTL
    Writes Invalidate Cache

    View full-size slide

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

    View full-size slide

  15. Least Recently Used

    View full-size slide

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

    View full-size slide

  17. Handling Events

    View full-size slide

  18. Event handling is a conversation

    View full-size slide

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

    View full-size slide

  20. Moving Pixels

    View full-size slide

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

    View full-size slide

  22. Write-Only DOM

    View full-size slide

  23. getOffsetHeight :
    74% slower than get className

    View full-size slide

  24. If you can, cache the
    value, not the node

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  28. User feedback comes first

    View full-size slide

  29. isSwiping = 1;

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  32. Run Animation in a
    Separate Thread

    View full-size slide

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

    View full-size slide

  34. Run Slow Code in a Worker*

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  37. UI Thread Handles Events
    and Orchestration

    View full-size slide

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

    View full-size slide

  39. 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

    View full-size slide