HOw to build Hybrid apps that don't
SUCK
Using Phonegap / Angularjs
Who AM I?
Jamie Sutherland
jamie@mallzee.com - @wedgybo
CTO @ Mallzee
Why should you listen to me?
You probably shouldn't.
I talk a lot of nonsense and the reason this talk exists is due to my stubbornness
of sticking with this stack even when things got tough.
Think you can do a better job. Get in touch with me
we're hiring :)
hybrid apps are
- Built with web technologies HTML5/JS
- Mixed with native components and APIs
- Not web apps
- A great prototyping tool - MVP
- Difficult to get towards native quality
phonegap/cordova
Tools to create hybrid apps
Provides JS APIs to native APIs via Plugins
Gets a bad rep because its seen at limited and the majority of apps are slow and clunky
(Ours included. Until now. By now I mean the one waiting to be released)
It's only limited by it's lack of Plugins and effort applied
(maybe some memory limitations in their too)
Should i build a hybrid app?
of course!
unless you have the following
Lots of images on screen at once
(Memory limits)
Copious complex animations
Copious complex animations
(Older phone limitations, JANK)
A talent for building native apps and know nothing about web development
A talent for building native apps and know nothing about web development
(why are you here?)
Using phonegap
npm install -g phonegap
Creating your first app
phonegap create edinburghjs com.edinburghjs.meetup EdinburghJS
Adding platforms
phonegap platform add ios
supported platforms: ios, android, blackberry, windows phone 7/8, FirefoxOS, fireos
How to install plugins
phonegap local plugin add https://github.com/mallzee/phonegap-facebook-plugin.git
Contacts, Network-Information, Splashscreen, StatusTap, FacebookConnect, Camera, Geolocation, FileAPI, Vibration, PushNotifications, and many more
AngularJS
Use yeoman - yeoman.io
npm install -g yo
Angular generator
npm install -g generator-angular
Create a project
yo angular edinburghjs
Install PhoneGap grunt tasks
npm install grunt-angular-phonegap
BASICS
Single Page Application (SPA)
Avoid external calls for view markup
If you must, cache it and check for new versions on the app startup
Avoid displaying large quantities of images at one time
VIEWs
Avoid complex DOM
If it's crazy, you're probably doing it wrong
Preload views using html2js
Devices
Multiple platforms/screen sizes?
phonegap local plugins add https://github.com/apache/cordova-plugin-device
Set the device type on the rootScope
function setDeviceType() { var model = device.model; // device is injected by the phonegap plugin if (model.match(/iPhone/) || model.match(/iPod/)) {
$rootScope.device = 'mobile';
} else if (model.match(/iPad/)) {
$rootScope.device = 'tablet';
}
}
ng-if and ng-switch are your friend add DOM when required
<div ng-if="device == 'tablet'">[ADD MORE STUFF IN HERE]</div>
Layout & CSS
Modern browsers. Modern CSS. flexbox
Minimise paint & style recalculations. 60FPS FTMFW!
Avoid box-shadow, opacity on older devices
Use classList instead of addClass
Add items to the GPU if they are moving. But not too much!
.movingItem { transform: translateZ(0); }
$ANIMATE
Animate your DOM elements with ease from css
.product.ng-enter,
.product.ng-leave {
-webkit-transition:0.5s ease all;
-moz-transition:0.5s ease all;
-o-transition:0.5s ease all;
transition:0.5s ease all;
}
.product.ng-enter,
.product.ng-leave.ng-leave-active {
opacity: 0;
}
.product.ng-leave,
.product.ng-enter.ng-enter-active {
opacity: 1;
}
$animate.enter(element, parent, sibling, callback)
DATA
Minimise external calls
Multiple HTTP calls are expensive
Group data if possible
You built the API? Awesome, create private endpoints to make your app snappier
Cache external data in localStorage
Always display cached data first then merge in new data when it becomes available
CACHE Merge
api.query(q, function (products) {
// Merge updates and remove
_.each(userProducts, function (p) {
var found = _.find(products.records, {'_id': p._id});
_.remove(products.records, {'_id': p._id});
if (found) {
_.merge(p, found);
} else {
p.__remove = true;
}
page++;
});
_.remove(userProducts, {'__remove': true});
_.each(products.records, function (newProduct) {
userProducts.push(newProduct);
});
localStorage.setItem('user.products', userProducts);
});
Stops a complete redraw of the list
Try animating a cache swap and you'll see why
PERFORMANCE TIPS
chrome timeline
Performance tips
batarang
PERFORMANCE TIPS
<div class="friends">
<a class="friend" ng-repeat="contact in contacts">
<h2 ng-bind="contact.name"></h2>
<img ng-src="contact.profile_image_url" />
</a>
</div>
Watches = 1
<div class="friends">
<a class="friend" bindonce ng-repeat="contact in contacts">
<h2 bo-text="contact.name"></h2>
<img bo-src="contact.profile_image_url" />
</a>
</div>
Performance hogs
Functions: Bad
<button ng-class="{'active': !productsFilter.isEmpty()}" ng-click="$state.go('filters')"></button>
functions: good
THEY ARE NOT. Avoid at all costs.
Write the result to a variable on the scope
<button ng-class="{'active': !productFilter.empty}" ng-click="$state.go('filters')"></button>
productFilter.empty = false;
function updateFilter() {
// Workout if the filters empty when and changes are made
...
empty = (filter.length > 0);
}
PERFORMANCE HOGS
Filters: Bad
<div class="price" ng-bind="product.price | currency:'£'"></div>
Filters: Good
Avoid filters in the view. Use $filter on your data
<div class="price" ng-bind="product.price"></div>
Mangle the data in your service/controller
angular.foEach(products, function(product) {
product.price = $filter('currency')(product.price, '£');
}
PERFORMANCE HOGS
ngRepeat
Watches can get out of hand quickly
Convenience leads to poor performance
Alternatives
quickNgRepeat - https://github.com/allaud/quick-ng-repeat
ngVirtualScroll - https://github.com/stackfull/angular-virtual-scroll
mlzUiTableView - https://github.com/mallzee/angular-ui-table-view
(shameless plug)
MEMORY LEAKS
Angular directives makes it easy to create memory (DOM/Event) leaks
$destroy everything
scope.$on('$destroy', function () { item.element.remove();
item.off('click'); });
angular modules
bower packages
angular-touch
angular-animate
angular-motion
angular-ui-utils
angular-ui-router
angular-strap
angular-carousel
angular-bindonce
angular-local-storage
angular-ui-table-view
restangular
Grunt tasks
jshint
less/sass
concat
usemin
imagemin
cssmin
htmlmin
uglyfy
ngmin
html2js
Awesome stuff to look @
Ionic Framework - http://ionicframework.com/
Steroids - http://developers.appgyver.com/
GREAT PHONEGAP APPS
Version 1.4.0 > :D
And I'm spent
Thanks for listening
PASS Me A BEER PLEASE :D
Direct all your love/abuse to me on twitter @wedgybo
Hybrid apps with Phonegap/AngularJS
By Jamie Sutherland
Hybrid apps with Phonegap/AngularJS
Hints and tips on how to create hybrid apps that don't suck with Phonegap/AngularJS.
- 7,193