developing better phonegap apps session 608 / devlearn 2013 daniel pfeiffer lead developer / float...
TRANSCRIPT
Developing Better PhoneGap AppsSession 608 / DevLearn 2013
Daniel PfeifferLead Developer / Float Mobile Learning
#DevLearn / Session 608 / Developing Better PhoneGap Apps
PhoneGap Overview
• Write your app using standards-based web technologies
• Access native OS features using JavaScript
• Deploy to multiple platforms with the same codebase
#DevLearn / Session 608 / Developing Better PhoneGap Apps
What PhoneGap is...
• A “wrapper” for your web-based apps
• A collection of standard APIs for accessing native device features across various platforms
• A standard for interacting between the native OS and JavaScript using plugins
Illustration by Adobe / Yohei Shimomae
#DevLearn / Session 608 / Developing Better PhoneGap Apps
What PhoneGap isn’t...
• Magic
• Compiler/translator that turns your web code into native (Objective-C, Java, etc.) code
• The answer for every mobile app
#DevLearn / Session 608 / Developing Better PhoneGap Apps
Web App vs. PhoneGap
Web App PhoneGap
Accessed via web browser
Installed as an app
Can be saved as a Web Clip
Locally available content
Able to cache some data locally
No storage limits
Easy to distribute/updateAdditional features
available through plugins
#DevLearn / Session 608 / Developing Better PhoneGap Apps
What is a “better” PhoneGap app?
• Responsive
• Runs “like a native app”
• Efficiently takes advantage of standards-based web technology while understanding the restrictions
• Considers the unique mobile affordances
• Maintainable
#DevLearn / Session 608 / Developing Better PhoneGap Apps
Abstraction Taxes
• PhoneGap provides an abstraction layer between your app logic and the native OS
• There are costs to using the abstraction layer:
- Performance restrictions
- Missing out on very finely tuned native user controls/inputs
Photo by Philip Taylor PT
#DevLearn / Session 608 / Developing Better PhoneGap Apps
var view = retrieveCurrentView();var newView = createNewView();view.parentNode.replaceChild(newView, view);
Don’t navigate away from index.html
•The time required to tear down a page and load a new one can be completely avoided
•Use JavaScript to change the DOM
#DevLearn / Session 608 / Developing Better PhoneGap Apps
Use touch events
• Users interact with mobile devices by touching—not clicking
• By default, most mobile browsers add ≈300ms delay for click events
• Try using the FastClick library
#DevLearn / Session 608 / Developing Better PhoneGap Apps
Communicate with your user
• Users should never have to wonder if the app is doing something
• Use loading indicators if something can’t be done instantly
• Remember, there is no “hover” state for buttons making a “down” state even more important
• Be prepared for users to hit buttons multiple times
#DevLearn / Session 608 / Developing Better PhoneGap Apps
<button class=”level”>1</button><button class=”level” disabled>1</button>
Use <button> instead of <a>
• Buttons are designed for handling user interactions while anchor tags are for linking between pages
• You can disable buttons by adding the disabled attribute
#DevLearn / Session 608 / Developing Better PhoneGap Apps
button:active { background-color: #F00;}
button:disabled { background-color: #CCC;}
Use CSS pseudo-classes
• :active to define the “down” state of buttons
• :disabled to define the “disabled” state of buttons
#DevLearn / Session 608 / Developing Better PhoneGap Apps
floatlearning.com on an iPhone 4
#DevLearn / Session 608 / Developing Better PhoneGap Apps
cnn.com on an iPhone 4
#DevLearn / Session 608 / Developing Better PhoneGap Apps
What is “reflow” (layout)?
• The time spent determining where elements will be drawn on the page is called “reflow”
• Reflow involves a lot of calculations as the browser determines how to layout the page
#DevLearn / Session 608 / Developing Better PhoneGap Apps
Reduce the cost of a reflow
• Calculations use the CPU—the more complicated the DOM, the more calculations, the longer it takes
• Remove extraneous tags to reduce DOM depth
<li><a href="#view1"> View 1</a></li>
#DevLearn / Session 608 / Developing Better PhoneGap Apps
Reduce the cost of a reflow
• Calculations use the CPU—the more complicated the DOM, the more calculations, the longer it takes
• Remove extraneous tags to reduce DOM depth
<li> View 1 </li>
#DevLearn / Session 608 / Developing Better PhoneGap Apps
Reduce the cost of a reflow
• Calculations use the CPU—the more complicated the DOM, the more calculations, the longer it takes
• Remove extraneous tags to reduce DOM depth
• Remove unused CSS rules
• Avoid complex CSS selectors where possible<li> View 1 </li>
#DevLearn / Session 608 / Developing Better PhoneGap Apps
var node = document.getElementById('some_element'),new_node = node.cloneNode(true);// Apply changes to the cloned nodevar a = document.createElement('span'),var b = document.createTextNode('some content');a.appendChild(b);new_node.innerHTML = '';new_node.appendChild(a);// Out with the old, in with the newnode.parentNode.replaceChild(new_node, node);
Reduce the number of reflows
• Avoid triggering unnecessary reflows
• Make batched changes to the DOM—don’t change one element at a time
#DevLearn / Session 608 / Developing Better PhoneGap Apps
var node = document.getElementById('some_element'),new_node = node.cloneNode(true);// Apply changes to the cloned nodevar a = document.createElement('span'),var b = document.createTextNode('some content');a.appendChild(b);new_node.innerHTML = '';new_node.appendChild(a);// Out with the old, in with the newnode.parentNode.replaceChild(new_node, node);
Reduce the number of reflows
• Avoid triggering unnecessary reflows
• Make batched changes to the DOM—don’t change one element at a time
#DevLearn / Session 608 / Developing Better PhoneGap Apps
Recalculate
$('#view').animate({width:'50%'});
Use CSS animations
• jQuery.animate performs custom animations on a set of CSS properties
• Changing size- or position-related CSS properties will trigger a reflow
Reflow Paint
#DevLearn / Session 608 / Developing Better PhoneGap Apps
#view { -webkit-transform: scale(.5,0);}
Use CSS animations
• CSS-based animations can skip the reflow process
• Some CSS-based animations are hardware accelerated and occur directly on the GPU
Paint
#DevLearn / Session 608 / Developing Better PhoneGap Apps
Consider client-side templating
• Helps provide a Model-View-Controller (MVC) structure to your application
• Enhances future maintainability of the code
• Enables you to keep the DOM free of nodes that are not needed
- Application views can be stored/manipulated in memory instead of in the DOM
- Only the active view lives in the DOM
#DevLearn / Session 608 / Developing Better PhoneGap Apps
Be mindful of memory usage
• Avoid excessive use of global variables
- The garbage collector clears data that is no longer in scope, but global variables are always in scope
- Code with well-defined scopes is easier to maintain
• Consider using smaller JavaScript frameworks
#DevLearn / Session 608 / Developing Better PhoneGap Apps
Share the work with plugins
• PhoneGap provides the standard for interacting between the native OS and JavaScript using plugins
• Take advantage of various OS features—including performance Illustration by Adobe / Yohei Shimomae
#DevLearn / Session 608 / Developing Better PhoneGap Apps
Measure
• Don’t make guesses as to what is causing your app to run slowly or crash
• Use the Safari Inspector or Instruments to measure your app and determine what to focus on improving
- Memory usage over time
- CPU usage over time
- Time spent in reflow
• Use aggregated analytics reports to determine what users like and what they won’t miss
#DevLearn / Session 608 / Developing Better PhoneGap Apps
Let’s review...
✓ Develop on the device—do not rely on the simulator
✓ Don’t navigate away from index.html
✓ Use touch events or the FastClick library
✓ Use pseudo-classes like :active or :disabled
✓ Keep the DOM simple
✓ Use CSS animations (especially hardware-accelerated animations where possible)
✓ Avoid global variables
✓ Use a smaller JS library