Your SlideShare is downloading. ×
QCON SP 2014: 10 dicas de desempenho para apps mobile hibridas
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×
Saving this for later? Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime – even offline.
Text the download link to your phone
Standard text messaging rates apply

QCON SP 2014: 10 dicas de desempenho para apps mobile hibridas

1,829

Published on

Palestra apresentada no dia 11 de abril de 2014 no QCON SP 2014

Palestra apresentada no dia 11 de abril de 2014 no QCON SP 2014

Published in: Technology
0 Comments
14 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
1,829
On Slideshare
0
From Embeds
0
Number of Embeds
2
Actions
Shares
0
Downloads
0
Comments
0
Likes
14
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide

Transcript

  • 1. 10 dicas de desempenho para apps mobile híbridas Loiane Groner http://loiane.com
  • 2. Me,Myself && I ! •Gerente de Desenv Projetos •8+ XP TI •Java JUG Leader •Sencha Community Leader •http://loiane.com •@loiane
  • 3. packpub.com ou amazon.com
  • 4. http://upgrade.ins-us.com/ Nov 2013
  • 5. I
  • 6. #1
  • 7. <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>!
  • 8. <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>!
  • 9. NÃO gere páginas no servidor
  • 10. Web Browser Dispositivo JavaScript Arquivos Imagens/ Documentos Banco de Dados caching
  • 11. 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
  • 12. JSON
  • 13. #2
  • 14. // Obtém dados! $.ajax({url: "getTrackInfo.php?id=1"}).done(function(track) {! // Mostra os detalhes - view! $.mobile.changePage($('#track-info'));! });!
  • 15. // Obtém dados! $.ajax({url: "getTrackInfo.php?id=1"}).done(function(track) {! // Mostra os detalhes - view! $.mobile.changePage($('#track-info'));! });!
  • 16. //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;! }! } !
  • 17. //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;! }! } !
  • 18. 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'! }! }! });!
  • 19. 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'! }! }! });!
  • 20. control: {! "contactslist": {! show: 'onListItemPainted'! }! }! ! //-------------------------------------! ! onListItemPainted: function(view, options) { ! view.getStore().load();! }!
  • 21. control: {! "contactslist": {! show: 'onListItemPainted'! }! }! ! //-------------------------------------! ! onListItemPainted: function(view, options) { ! view.getStore().load();! }!
  • 22. Mostre a view e depois carregue os dados
  • 23. #3
  • 24. 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'! }! ]! }! ! });!
  • 25. 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'! }! ]! }! ! });!
  • 26. Be LAZY
  • 27. #4
  • 28. App com lista dos participantes do QCON SP 2014
  • 29. select count(*) from ParticipantesQCONSP App com lista dos participantes do QCON SP 2014
  • 30. select count(*) from ParticipantesQCONSP == 1000 App com lista dos participantes do QCON SP 2014
  • 31. select count(*) from ParticipantesQCONSP == 1000 App com lista dos participantes do QCON SP 2014 É muito dado?
  • 32. Paging / Paginação https://github.com/stakbit/jQuery-Mobile-Listview-Pagination-Plugin http://dcarrith.github.io/jquery.mobile.lazyloader/
  • 33. $.ajax({url: "listaEstadosBr.php"}).done(function(data) {! estadosBr = data;! });!
  • 34. $.ajax({url: "listaEstadosBr.php"}).done(function(data) {! estadosBr = data;! });!
  • 35. Dados Estáticos LocalStorage SQLite - database Arquivo - JSON
  • 36. // 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
  • 37. // 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
  • 38. Faça cache dos dados
  • 39. #5
  • 40. 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;! });!
  • 41. 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;! });!
  • 42. Evite CLICK use TOUCHEND
  • 43. Fastclick https://github.com/ftlabs/fastclick
  • 44. $("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;! });!
  • 45. $("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;! });!
  • 46. #6
  • 47. $("#page").animate();!
  • 48. $("#page").animate();!
  • 49. .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;! }!
  • 50. .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;! }!
  • 51. Use CSS 3 Transitions + Hardware Acceleration
  • 52. .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;! }!
  • 53. .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;! }!
  • 54. Page Slider https://github.com/ccoenraets/PageSlider
  • 55. #7
  • 56. • box-shadow • border-radius • gradients • text-align
  • 57. • box-shadow • border-radius • gradients • text-align
  • 58. Evite sombras e gradientes
  • 59. #8
  • 60. $("#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");!
  • 61. $("#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");!
  • 62. 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');!
  • 63. 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');!
  • 64. var $backBtn = $('#contato-info a.back');! $backBtn.on("touchend", clickHandler);! $backBtn.attr("href", "#contato-info");! $backBtn.css("color", "green");! $backBtn.css("text-decoration", "none");!
  • 65. var $backBtn = $('#contato-info a.back');! $backBtn.on("touchend", clickHandler);! $backBtn.attr("href", "#contato-info");! $backBtn.css("color", "green");! $backBtn.css("text-decoration", "none");!
  • 66. var backBtn = Ext.ComponentQuery.query('contactinfo button#back')[0];! backBtn.on('tap', clickHandler);! backBtn.setCls('backBtn');! backBtn.setLabelCls('labelCls');!
  • 67. var backBtn = Ext.ComponentQuery.query('contactinfo button#back')[0];! backBtn.on('tap', clickHandler);! backBtn.setCls('backBtn');! backBtn.setLabelCls('labelCls');!
  • 68. Minimize Browser Reflows
  • 69. #9
  • 70. XUI
  • 71. 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.'! );! }! });!
  • 72. Topcoat
  • 73. Cuidado com framework / lib da moda
  • 74. #10
  • 75. .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;! }!
  • 76. .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;! }!
  • 77. .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;! }!
  • 78. .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;! }!
  • 79. Build Otimizado Agrega Valor!
  • 80. http://jquerymobile.com/download-builder/
  • 81. http://jquerymobile.com/download-builder/
  • 82. OTIMIZE JS,CSS,HTML
  • 83. http://browserdiet.com/pt/
  • 84. https://github.com/loiane/mobile-hibrido-performance
  • 85. http://loiane.com facebook.com/loianegroner @loiane https://github.com/loiane youtube.com/user/Loianeg
  • 86. Obrigada!

×