• Share
  • Email
  • Embed
  • Like
  • Save
  • Private Content
Mobile optimization
 

Mobile optimization

on

  • 2,025 views

PhoneGap Training - Optimus Prime...

PhoneGap Training - Optimus Prime

"More computing sins are committed in the name of efficiency (without necessarily achieving it) than for any other single reason — including blind stupidity."
— W.A. Wulf

Statistics

Views

Total Views
2,025
Views on SlideShare
2,022
Embed Views
3

Actions

Likes
2
Downloads
49
Comments
0

1 Embed 3

http://a0.twimg.com 3

Accessibility

Categories

Upload Details

Uploaded via as Apple Keynote

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n

Mobile optimization Mobile optimization Presentation Transcript

  • Mobile OptimizationJesse MacFadyen
  • Optimus Prime"More computing sins are committed in the name ofefficiency (without necessarily achieving it) than for anyother single reason — including blind stupidity." —W.A. Wulf
  • About MeWith Nitobi for the last 3 yearsBuilt many large scale JS Apps for Mobile devices.PhoneGap contributor ( iOS + WP7 )
  • What is Optimization?
  • 2 CategoriesTime vs Space- Balance is the key.
  • When should you optimize?When you noticeperformance lagOften, each iterationReview at the endof each releasecycle
  • What to optimizeIt has been said that when an application is running, 90% of the time is spent in 10% of the code. Find the 10%
  • BenchmarkingIt is hard to judge improvement without measurement. console.log("running test 1") var startTime = new Date().getTime(); /// lots of looping in here var elapsed = new Date().getTime() - startTime; console.log("Test 1 took : " + elapsed);
  • A quick demo.
  • What does this tell us? Run your loops a lot! Be somewhat realistic If it aint broke, dont fix it!
  • Know when to optimize function doIt(a,b,c,d,e) { if(typeof a === "function") { a(b,c,d,e); } else { throw "wtf?"; } }
  • Minification There are tools for that This is an extreme example, but it happens. Trust me. Add a minification tool to your build process.
  • Minification Tools JSMin http://www.crockford.com/javascript/jsmin.html YUI Compressor http://developer.yahoo.com/yui/compressor/ Closure http://code.google.com/closure/Minification does not improve execution time of your code!
  • More Tools - Quality JSLint, by Douglas Crockford http://www.jslint.com/ JSHint, based on JSLint http://www.jshint.com/
  • Concatenation Combining multiple input files into a single file request can help with load times as well. PhoneGap uses this technique for the JS code in phonegap.js.
  • More coding tips : Dereference long variables or frequently used variables with a local alias.
  • Long object referenceex. ( Bad )function findUserById(id){ for(var n = 0; n < app.model.userInfo.contacts.length; n++) { if(app.model.userInfo.contacts[n].id === id) { return app.model.userInfo.contacts[n]; } }}
  • Dereferenced Object Aliasex. ( Better )function ndUserById(id){ var contacts = app.model.userInfo.contacts; for(var n = 0, len=contacts.length; n < len; n++) { if(contacts[n].id === id) { return contacts[n]; } }}
  • What really happens with long object chains:Because we store a local alias to the contacts array, wedont have to dereference repeatedly.app.model.userInfo.contactsfind a var named appfind a property named modelfind a property named userInfofind a property named contacts
  • Using the right container-- assuming ids are unique in thecontacts list :function findUserById(id){ // no searching ... returnapp.model.userInfo.contacts[id];}
  • // and when we received them from the server, we probably// got them like this:// Bad?function onServerResult(res){ for(var n = 0; n < res.length; n++) { var contact = JSON.parse(res[n]); app.model.userInfo.contacts[contact.id] = contact; }}
  • // what about lifting?// thats betterfunction onServerResult(res){ var contacts = app.model.userInfo.contacts; var contact; for(var n = 0; n < res.length; n++) { contact = JSON.parse(res[n]); contacts[contact.id] = contact; }}
  • Switch vs If/ElseDemo of an extreme case
  • Switch on Boolean// validate a formswitch(true){ case ( usernameTxt.value == null) : // set error message, set focus, ... return false; case ( passwordTxt.value == null) : return false; case ( passwordTxt.value != password2Text.value) return false;}Always put your most likely cases rst, to avoid extra processing.Exit as soon as possible, if you found it, then stop looking.
  • Key questions to askIs the performance really that bad?Perception is key.Does your app remain responsive?
  • var processedIndex = 0;var jobs = [];function processNextValue(){ if(processedIndex < jobs.length) { doJob(jobs[processedIndex++]); setTimeout(processNextValue,1); }}function doJob(job){ // assume some short bit of work here}function onTouchStart(e){ // you could even pause your processing in here}function onCancelButton(e){ // cancel your jobs}
  • On to the DOMThe DOM is your friend, be nice to it!
  • A common performancekiller is this nasty tidbit : for(var n = 0; n < results.length; n++) { var elementMarkup = "<li class=resultItem>" + results[n] + "</li>"; document.getElementById("resultList").innerHTML += elementMarkup; }
  • Prepare your updates to the DOMvar elementsMarkup = "";for(var n = 0; n < results.length; n++){ elementsMarkup += "<li class=resultItem>" + results[n] + "</li>"}document.getElementById("resultList").innerHTML += elementsMarkup; Now we are only modifying the DOM once, and it can be updated quickly.
  • DOM best practices if you can avoid using css gradients, then drop them. They are heavy to render, especially in scrolling lists. avoid transparency where possible. If an item is transparent, the stuff behind it needs to be rendered too. use 3D transforms for moving/sliding DOM elements. Most newer devices use hardware acceleration for 3D transforms. Essentially you will just throw away the Z.ex.Slide right :element.style.webkitTransitionDuration = "600ms";element.style.webkitTransform = "translate3D(-320px,0px,0px)";An example of this later.
  • Sprite SheetsInstead of loading many small icons, or UI elements asseparate images, consider compositing them into oneimage file and using css properties to manipulate whatarea is shown.http://www.tutorial9.net/tutorials/web-tutorials/building-faster-websites-with-css-sprites/And there are tools to help you.http://spritegen.website-performance.org/... many out there, look around.
  • Using Libraries There are millions out there! ( okay, hundreds ) Most will work with PhoneGap jQuery Mobile - the big name Sencha Touch - rich interaction Dojo Mobile XUI - Nitobi’s own - Nitobis own
  • Do you need a UI framework? You may not need a full blown UI Framework, there are also lighter options to consider. Backbone.js gives you a nice scaffold, and helpers for managing your app. Underscore.js is JS utility belt, helpers for function binding, ...
  • That elusive scrollingiScroll4My favorite scrolling library ( even over my own )A very common request, how do we make some things scroll,while other things dont?iScroll works with iOS and Android, and has nodependancies.Follow a few simple rules, and you can have nice scrollingcontent with scrollbars.
  • Ekiben Demoopen source MIT in github/purplecabbage/ekiben
  • General Considerationsfollow MVC conventions, and keep a clear separationbetween the views of your app.keep things async, and try to implementeventListeners, or some notification system.scripts at the bottom!
  • More Crazy Goodness// Write your own query selectorfunction $(query){ return document.querySelectorAll(query);}More here :http://cubiq.org/do-you-really-need-jquery-for-mobile-dev
  • Function.prototype.bind = function(sub){ var me = this; return function(){ return me.apply(sub, arguments);};};Just call like this :someObject.myFunk = function(){ // this is this of someObject}someObject.doLater = function(){ setInterval( this.myFunk.bind(this),1000);}