340 likes | 504 Views
Developing Better PhoneGap Apps. Session 608 / DevLearn 2013 Daniel Pfeiffer Lead Developer / Float Mobile Learning. PhoneGap Overview. Write your app using standards-based web technologies Access native OS features using JavaScript Deploy to multiple platforms with the same codebase.
E N D
Developing Better PhoneGap Apps • Session 608 / DevLearn 2013 • Daniel Pfeiffer • Lead Developer / Float Mobile Learning
PhoneGap Overview • Write your app using standards-based web technologies • Access native OS features using JavaScript • Deploy to multiple platforms with the same codebase
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
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
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
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
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 var view = retrieveCurrentView(); var newView = createNewView(); view.parentNode.replaceChild(newView, view);
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
Demo • Touch events vs. Click events
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
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 <button class=”level”>1</button> <button class=”level”disabled>1</button>
Use CSS pseudo-classes • :active to define the “down” state of buttons • :disabled to define the “disabled” state of buttons button:active { background-color: #F00; } button:disabled { background-color: #CCC; }
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
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>
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>
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>
Reduce the number of reflows • Avoid triggering unnecessary reflows • Make batched changes to the DOM—don’t change one element at a time var node = document.getElementById('some_element'), new_node = node.cloneNode(true); // Apply changes to the cloned node var 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 new node.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 var node = document.getElementById('some_element'), new_node = node.cloneNode(true); // Apply changes to the cloned node var 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 new node.parentNode.replaceChild(new_node, node);
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 Recalculate Reflow Paint $('#view').animate({width:'50%'});
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 #view { -webkit-transform: scale(.5,0); }
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
Demo • jQuery-based vs. CSS animations
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
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
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
Demo • Measuring your app
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
Questions? • @mediabounds • dpfeiffer@floatlearning.com • www.floatlearning.com/blog/phonegap