FrontInterior 2014: 10 dicas de desempenho para apps mobile hibridas

Preview:

DESCRIPTION

FrontInterior 2014: 10 dicas de desempenho para apps mobile hibridas. Bauru - SP - 30 de agosto de 2014

Citation preview

10 dicas de desempenho para apps mobile híbridas

Loiane Groner http://loiane.com

Me, Myself && I

!

•Gerente de Desenv Projetos

•8+ XP TI

•Java, Sencha, Phonegap

•Cozinheira amadora

•http://loiane.com

•@loiane

packpub.com amazon.com.br

livrariacultura.com.br

http://upgrade.ins-us.com/

Nov 2013

I

#1

<div data-role="page" id="tracks">!! <div data-role="header"><h1>Tracks</h1></div>!! <ul data-role="listview">!! <li><a href="getTrackInfo.php?id=1">Desempenho e Escalabilidade na Prática</a></li>!! <li><a href="getTrackInfo.php?id=2">Java na Crista da Onda</a></li>!! <li><a href="getTrackInfo.php?id=3">Arquiteturas que Você Sempre Quis Conhecer</a></li>!! <li><a href="getTrackInfo.php?id=4">Mobile: Portáteis e Furiosos</a></li>!! </ul>!</div>!

<div data-role="page" id="tracks">!! <div data-role="header"><h1>Tracks</h1></div>!! <ul data-role="listview">!! <li><a href="getTrackInfo.php?id=1">Desempenho e Escalabilidade na Prática</a></li>!! <li><a href="getTrackInfo.php?id=2">Java na Crista da Onda</a></li>!! <li><a href="getTrackInfo.php?id=3">Arquiteturas que Você Sempre Quis Conhecer</a></li>!! <li><a href="getTrackInfo.php?id=4">Mobile: Portáteis e Furiosos</a></li>!! </ul>!</div>!

NÃO gere páginas no servidor

Web Browser

Dispositivo

JavaScript

Arquivos Imagens/

Documentos

Banco de Dados caching

Web Browser

Dispositivo

Web Server

Java/PHP/Ruby/C#

Arquivos Imagens/

Documentos

Banco de Dados

Backend

http://

Lógica de negócio

JavaScript

Arquivos Imagens/

Documentos

Banco de Dados caching

JSON

#2

// Obtém dados!$.ajax({url: "getTrackInfo.php?id=1"}).done(function(track) {! // Mostra os detalhes - view! $.mobile.changePage($('#track-info'));!});!

// Obtém dados!$.ajax({url: "getTrackInfo.php?id=1"}).done(function(track) {! // Mostra os detalhes - view! $.mobile.changePage($('#track-info'));!});!

//mostra View!$.mobile.changePage($('#track-info'));!!//------------------------------------------------------------------------!!$(document).bind("pagechange", onPageChange);!!function onPageChange(event, data) {!! var toPageId = data.toPage.attr("id");!!! switch (toPageId) {! case 'track-info':! ! ! clearValues();!! ! // Obtém dados!! ! ! $.ajax({url: "getTrackInfo.php?id=1"}).done(function(track) {!! ! ! // Atualiza os detalhes - view!! ! ! $('#trackNome h1').html(track.name);!! ! ! ! $('#trackDesc').val(track.desc);!! ! ! ! $('#trackDia').val(track.dia);!! ! ! ! $('#trackLocal').val(track.local);!! ! ! ! $('#trackHost').val(track.host);!! ! ! });! ! ! ! break;! }!} !

//mostra View!$.mobile.changePage($('#track-info'));!!//------------------------------------------------------------------------!!$(document).bind("pagechange", onPageChange);!!function onPageChange(event, data) {!! var toPageId = data.toPage.attr("id");!!! switch (toPageId) {! case 'track-info':! ! ! clearValues();!! ! // Obtém dados!! ! ! $.ajax({url: "getTrackInfo.php?id=1"}).done(function(track) {!! ! ! // Atualiza os detalhes - view!! ! ! $('#trackNome h1').html(track.name);!! ! ! ! $('#trackDesc').val(track.desc);!! ! ! ! $('#trackDia').val(track.dia);!! ! ! ! $('#trackLocal').val(track.local);!! ! ! ! $('#trackHost').val(track.host);!! ! ! });! ! ! ! break;! }!} !

Ext.define('MyContacts.store.Contacts', {! extend: 'Ext.data.Store',!! requires: [! 'MyContacts.model.Contact',! 'MyContacts.proxy.ContactsProxy'! ],!! config: {! autoLoad: true,! model: 'MyContacts.model.Contact',! storeId: 'Contacts',! proxy: {! type: 'contactstorage'! }! }!});!

Ext.define('MyContacts.store.Contacts', {! extend: 'Ext.data.Store',!! requires: [! 'MyContacts.model.Contact',! 'MyContacts.proxy.ContactsProxy'! ],!! config: {! autoLoad: true,! model: 'MyContacts.model.Contact',! storeId: 'Contacts',! proxy: {! type: 'contactstorage'! }! }!});!

control: {! "contactslist": {! show: 'onListItemPainted'! }!}!!//-------------------------------------!!onListItemPainted: function(view, options) { ! view.getStore().load();!}!

control: {! "contactslist": {! show: 'onListItemPainted'! }!}!!//-------------------------------------!!onListItemPainted: function(view, options) { ! view.getStore().load();!}!

Mostre a view e depois carregue os

dados

#3

Ext.define('MyContacts.view.ContactsPanel', {! extend: 'Ext.Container',! alias: 'widget.contactspanel',!! requires: [! 'MyContacts.view.ContactsList',! 'MyContacts.view.ContactInfo',! 'MyContacts.view.ContactEdit'! ],!! config: {! layout: {! type: 'card'! },! items: [! {! xtype: 'contactslist'! },! {! xtype: 'contactinfo'! },! {! xtype: 'contactedit'! }! ]! }!!});!

Ext.define('MyContacts.view.ContactsPanel', {! extend: 'Ext.Container',! alias: 'widget.contactspanel',!! requires: [! 'MyContacts.view.ContactsList',! 'MyContacts.view.ContactInfo',! 'MyContacts.view.ContactEdit'! ],!! config: {! layout: {! type: 'card'! },! items: [! {! xtype: 'contactslist'! },! {! xtype: 'contactinfo'! },! {! xtype: 'contactedit'! }! ]! }!!});!

Be LAZY

#4

App com lista dos participantes do FrontInterior

select count(*) from Participantes

App com lista dos participantes do FrontInterior

select count(*) from Participantes

== 1000

App com lista dos participantes do FrontInterior

select count(*) from Participantes

== 1000

App com lista dos participantes do FrontInterior

É muito dado?

Paging / Paginação

https://github.com/stakbit/jQuery-Mobile-Listview-Pagination-Plugin

http://dcarrith.github.io/jquery.mobile.lazyloader/

$.ajax({url: "listaEstadosBr.php"}).done(function(data) {! estadosBr = data;!});!

$.ajax({url: "listaEstadosBr.php"}).done(function(data) {! estadosBr = data;!});!

Dados Estáticos

LocalStorage SQLite - database Arquivo - JSON

// do a SERVER load, passing a callback function!offlineSyncStore.loadServer(function(){!! // create a new Person record! var person = Ext.create('Person', {! FirstName: 'Joe',! LastName: 'Bloggs',! Email: 'joe@swarmonline.com'! });!! // add it to the store! offlineSyncStore.add(person);!! // sync the store LOCALLY. If autoServerSync is set to true then this will also sync using SERVER proxy! offlineSyncStore.sync();!! // if autoServerSync is false then call SERVER sync manually! offlineSyncStore.syncServer();!!});!

https://market.sencha.com/extensions/ext-ux-offlinesyncstore

// do a SERVER load, passing a callback function!offlineSyncStore.loadServer(function(){!! // create a new Person record! var person = Ext.create('Person', {! FirstName: 'Joe',! LastName: 'Bloggs',! Email: 'joe@swarmonline.com'! });!! // add it to the store! offlineSyncStore.add(person);!! // sync the store LOCALLY. If autoServerSync is set to true then this will also sync using SERVER proxy! offlineSyncStore.sync();!! // if autoServerSync is false then call SERVER sync manually! offlineSyncStore.syncServer();!!});!

https://market.sencha.com/extensions/ext-ux-offlinesyncstore

Faça cache dos dados

#5

var timeTouch;!!$("body").on("touchend", ".needsclick", function() {! timeTouch = new Date().getTime();!});!!$("body").on("click", ".needsclick", function() {! if (timeTouch) {! $("#log-slow").html("click: " + (new Date().getTime() - timeTouch) + "ms");! }! return false;!});!

var timeTouch;!!$("body").on("touchend", ".needsclick", function() {! timeTouch = new Date().getTime();!});!!$("body").on("click", ".needsclick", function() {! if (timeTouch) {! $("#log-slow").html("click: " + (new Date().getTime() - timeTouch) + "ms");! }! return false;!});!

Evite CLICK use TOUCHEND

Fastclick

https://github.com/ftlabs/fastclick

$("body").on("touchend", ".fastclick", function() {! timeTouch = new Date().getTime();!});!!$("body").on("click", ".fastclick", function() {! if (timeTouch) {! $("#log-fast").html("touchend: " + (new Date().getTime() - timeTouch) + "ms");! } else {! alert("Execute esse exemplo em um device touch");! }! return false;!});!

$("body").on("touchend", ".fastclick", function() {! timeTouch = new Date().getTime();!});!!$("body").on("click", ".fastclick", function() {! if (timeTouch) {! $("#log-fast").html("touchend: " + (new Date().getTime() - timeTouch) + "ms");! } else {! alert("Execute esse exemplo em um device touch");! }! return false;!});!

$("body").on("touchend", ".fastclick", function() {! timeTouch = new Date().getTime();!});!!$("body").on("click", ".fastclick", function() {! if (timeTouch) {! $("#log-fast").html("touchend: " + (new Date().getTime() - timeTouch) + "ms");! } else {! alert("Execute esse exemplo em um device touch");! }! return false;!});!

#6

$("#page").animate();!

$("#page").animate();!

.page {! position: absolute;! width: 200px;! height:200px;! top:20px;! left:50;!}!!.page-left {! left: 50px;!}!.page-center {! left: 275px;!}!.page-right {! left: 500px;!}!!.transition {! transition-duration: .25s;!}!

.page {! position: absolute;! width: 200px;! height:200px;! top:20px;! left:50;!}!!.page-left {! left: 50px;!}!.page-center {! left: 275px;!}!.page-right {! left: 500px;!}!!.transition {! transition-duration: .25s;!}!

.page {! position: absolute;! width: 200px;! height:200px;! top:20px;! left:50;!}!!.page-left {! left: 50px;!}!.page-center {! left: 275px;!}!.page-right {! left: 500px;!}!!.transition {! transition-duration: .25s;!}!

Use CSS 3 Transitions +

Hardware Acceleration

.page {! position: absolute;! width: 200px;! height:200px;! top:20px;! left:50;! transform: translate3d(0,0,0);!}!!.page-left {! -webkit-transform: translate3d(30px, 0, 0);! transform: translate3d(31px, 0, 0);!}!.page-center {! -webkit-transform: translate3d(250px, 0, 0);! transform: translate3d(251px, 0, 0);!}!.page-right {! -webkit-transform: translate3d(470px, 0, 0);! transform: translate3d(471px, 0, 0);!}!!.transition {! -webkit-transition-duration: .25s;! transition-duration: .25s;!}!

.page {! position: absolute;! width: 200px;! height:200px;! top:20px;! left:50;! transform: translate3d(0,0,0);!}!!.page-left {! -webkit-transform: translate3d(30px, 0, 0);! transform: translate3d(31px, 0, 0);!}!.page-center {! -webkit-transform: translate3d(250px, 0, 0);! transform: translate3d(251px, 0, 0);!}!.page-right {! -webkit-transform: translate3d(470px, 0, 0);! transform: translate3d(471px, 0, 0);!}!!.transition {! -webkit-transition-duration: .25s;! transition-duration: .25s;!}!

.page {! position: absolute;! width: 200px;! height:200px;! top:20px;! left:50;! transform: translate3d(0,0,0);!}!!.page-left {! -webkit-transform: translate3d(30px, 0, 0);! transform: translate3d(31px, 0, 0);!}!.page-center {! -webkit-transform: translate3d(250px, 0, 0);! transform: translate3d(251px, 0, 0);!}!.page-right {! -webkit-transform: translate3d(470px, 0, 0);! transform: translate3d(471px, 0, 0);!}!!.transition {! -webkit-transition-duration: .25s;! transition-duration: .25s;!}!

Page Slider

https://github.com/ccoenraets/PageSlider

#7

• box-shadow • border-radius • gradients • text-align

• box-shadow • border-radius • gradients • text-align

Evite sombras e gradientes

#8

$("#contato-info a.back").on("touchend", clickHandler);!$("#contato-info a.back").attr("href", "#contato-info");!$("#contato-info a.back").css("color", "green");!$("#contato-info a.back").css("text-decoration", "none");!

$("#contato-info a.back").on("touchend", clickHandler);!$("#contato-info a.back").attr("href", "#contato-info");!$("#contato-info a.back").css("color", "green");!$("#contato-info a.back").css("text-decoration", "none");!

$("#contato-info a.back").on("touchend", clickHandler);!$("#contato-info a.back").attr("href", "#contato-info");!$("#contato-info a.back").css("color", "green");!$("#contato-info a.back").css("text-decoration", "none");!

Ext.ComponentQuery.query('contactinfo button#back')[0].on('tap', clickHandler);!Ext.ComponentQuery.query('contactinfo button#back')[0].setCls('backBtn');!Ext.ComponentQuery.query('contactinfo button#back')[0].setLabelCls('labelCls');!

Ext.ComponentQuery.query('contactinfo button#back')[0].on('tap', clickHandler);!Ext.ComponentQuery.query('contactinfo button#back')[0].setCls('backBtn');!Ext.ComponentQuery.query('contactinfo button#back')[0].setLabelCls('labelCls');!

var $backBtn = $('#contato-info a.back');!$backBtn.on("touchend", clickHandler);!$backBtn.attr("href", "#contato-info");!$backBtn.css("color", "green");!$backBtn.css("text-decoration", "none");!

var $backBtn = $('#contato-info a.back');!$backBtn.on("touchend", clickHandler);!$backBtn.attr("href", "#contato-info");!$backBtn.css("color", "green");!$backBtn.css("text-decoration", "none");!

var backBtn = Ext.ComponentQuery.query('contactinfo button#back')[0];!backBtn.on('tap', clickHandler);!backBtn.setCls('backBtn');!backBtn.setLabelCls('labelCls');!

var backBtn = Ext.ComponentQuery.query('contactinfo button#back')[0];!backBtn.on('tap', clickHandler);!backBtn.setCls('backBtn');!backBtn.setLabelCls('labelCls');!

Minimize Browser Reflows

#9

XUI

x$(document).on("deviceready", function () {!! headingDiv = x$("#heading");! navigator.compass.getCurrentHeading(onSuccess, onError);! navigator.compass.watchHeading(onSuccess, onError, {frequency: 100});!! function onSuccess(heading) {! headingDiv.html(! 'Heading: ' + heading.magneticHeading + '&#xb0; ' +! convertToText(heading.magneticHeading) + '<br />' +! 'True Heading: ' + heading.trueHeading + '<br />' +! 'Accuracy: ' + heading.headingAccuracy! );! ! // Alter the CSS properties to rotate the rose image! x$(".rose").css({! "-webkit-transform":! "rotate(-" + heading.magneticHeading + "deg)",! "transform":! "rotate(-" + heading.magneticHeading + "deg)"! });! }!! function onError() {! headingDiv.html(! 'There was an error trying to ' +! 'locate your current bearing.'! );! }!});!

Topcoat

Cuidado com framework / lib da

moda

#10

.icon-user {! background-image: url(../images/user.png) !important;!}!!.icon-user-add {! background-image: url(../images/user_add.gif) !important;!}!!.icon-save {! background-image: url(../images/save.gif) !important;!}!!.icon-reset {! background-image: url(../images/stop.png) !important;!}!!.icon-grid {! background-image: url(../images/grid.png) !important;!}!!.icon-add {! background-image: url(../images/add.png) !important;!}!!.icon-delete {! background-image: url(../images/delete.png) !important;!}!

.icon-user {! background-image: url(../images/user.png) !important;!}!!.icon-user-add {! background-image: url(../images/user_add.gif) !important;!}!!.icon-save {! background-image: url(../images/save.gif) !important;!}!!.icon-reset {! background-image: url(../images/stop.png) !important;!}!!.icon-grid {! background-image: url(../images/grid.png) !important;!}!!.icon-add {! background-image: url(../images/add.png) !important;!}!!.icon-delete {! background-image: url(../images/delete.png) !important;!}!

.icon {!! background-image:url(result.png);!}!!.icon-user {! background-position: 0px -156px;!}!!.icon-user-add {! background-position: 0px -130px;!}!!.icon-save {! background-position: 0px -78px;!}!!.icon-reset {! background-position: 0px -104px;!}!!.icon-grid {! background-position: 0px -52px;!}!!.icon-add {! background-position: 0px 0px;!}!!.icon-delete {! background-position: 0px -26px;!}!

.icon {!! background-image:url(result.png);!}!!.icon-user {! background-position: 0px -156px;!}!!.icon-user-add {! background-position: 0px -130px;!}!!.icon-save {! background-position: 0px -78px;!}!!.icon-reset {! background-position: 0px -104px;!}!!.icon-grid {! background-position: 0px -52px;!}!!.icon-add {! background-position: 0px 0px;!}!!.icon-delete {! background-position: 0px -26px;!}!

Build Otimizado

Agrega Valor!

http://jquerymobile.com/download-builder/

http://jquerymobile.com/download-builder/

OTIMIZE JS, CSS, HTML

http://browserdiet.com/pt/

https://github.com/loiane/mobile-hibrido-performance

http://loiane.com

facebook.com/loianegroner

@loiane

https://github.com/loiane

youtube.com/user/Loianeg

Obrigada!

Recommended