Ionic Framework

A introdução que faltava ao Ionic 2

Era uma vez…

Há cerca de dois anos e meio eu postei o meu primeiro artigo sobre o Ionic Framework (Aplicativos mobile com o AngularJS e Ionic) e desde então Web Platform evoluiu, o ES6 passou a se chamar ES2015 e falta pouco para ser totalmente suportado pelos navegadores, o ES7 virou ES2016 e está logo ali.

Ferramentas como Babel, Typescript e Flow se tornaram comuns. Grunt e Gulp foram aos poucos sendo substituídos pelo Webpack (e o Rollup.js já tá vindo aí). Além disso, o código front-end evoluiu pra uma arquitetura baseada em componentes e isso muito se deve ao React e seus derivados.

E nesse novo mundo front-end o AngularJS 1.x perdeu espaço. O two-way data binding que nós tanto gostávamos era, na verdade, sofrível para a performance. Os escopos eram uma zona. Tínhamos várias formas de fazer a mesma coisa (controller vs directive, service vs factory). A declaração de diretivas era muito complexa. E, por fim, não era possível fazer Server Side Rendering (a não ser que você fosse pelo longo e tortuoso caminho dos hacks obscuros).

E apesar de tudo isso o Ionic Framework continuava sendo uma ferramenta fantástica. Ele possibilitou que muitos de nós conseguissemos criar nossas aplicações sem perder tempo escrevendo o mesmo código de diferentes formas pra duas ou mais plataformas.

Porém, isso não quer dizer que ele não tinha seus problemas. Tinha sim. E muitos. O Ionic Framework foi inicialmente pensado para o iOS e lá ele funcionava muito bem, inclusive com look and feel nativo. Só depois ele foi sendo adaptado (leia-se: remendado) para o Android. E isso nunca permitiu que ele fosse um framework 100% lá. Além disso, no Android, nós temos uma infinidade de dispositivos com inúmeras características de software, performance, resolução, sensores, etc. que prejudicavam ainda mais a experiência no sistema operacional.

É claro que com um pouco de trabalho duro era possível alcançar um nível de qualidade aceitável em nossos aplicativos. E, como bem sabemos, a lei de Moore tá aí pra deixar nossos aplicativos legados cada dia mais rápidos.

Recomeço

Mas vamos avançar um pouco no tempo.

Com todo o aprendizado adquirido pela comunidade front-end nos últimos anos a equipe do AngularJS decidiu reescrever ele inteiro para atender as necessidades dos aplicativos do presente (quiçá do futuro) e, por mais que a ideia fosse boa e, provavelmente, necessária, houve resistência da comunidade. Afinal seria necessário reaprender a usar o Angular. A comunidade ficou dividida.

Mas o que parecia um problema para a equipe do Ionic pode ter se tornado o seu maior trunfo. Com a eminência do Angular 2 e sua total reescrita a equipe do Ionic decidiu comprar a ideia e também reescrever o Ionic. Só que agora usando todo o conhecimento adquirido ao longo dos anos de desenvolvimento do framework.

E hoje, meus amigos, foi lançada oficialmente a nova versão do Ionic. Eu já tenho usado o Ionic 2 desde o beta 4, ou seja, já tem quase 1 ano e posso dizer que passei por uns perrengues por ser early adopter, mas ele evoluiu muito quando comparado ao seu antecessor.

Ainda temos alguns bugs, mas, no geral, uma aplicação criada com o Ionic 2 é muito, mas muito, mas muito melhor que uma criada no Ionic 1. Sem contar que é muito mais fácil dar manutenção conforme a aplicação vai crescendo.

O que tem de novo?

Por herdar as caracaterísticas do Angular 2, o framework agora é mais performático e é basicamente Javascript, ao contrário do Angular 1 (onde precisávamos aprender um monte de coisas pra podermos trabalhar [$scope, $q, controller, directive, etc.]).

É importante ressaltar que agora nós podemos tirar proveito do ES2015 ES6 (tecnicamente é Typescript) para manter nosso código melhor, mais legível e organizado.

O Ionic 2 foi projetado com o conceito de temas, ou seja, por padrão ele já segue as guidelines de design do iOS, do Material Design e do Windows Phone. A estrutura e a forma de personalizar os componentes também ficaram muito mais claros, já que o SASS está mais bem estruturado e o processo de build já vem com ele configurado out of the box.

Por falar em estrutura e build, o Ionic 2 está muito mais simples e organizado nesses pontos. Não temos mais várias formas de fazer as mesmas coisas. Possuímos uma CLI que nos ajuda a gerar automaticamente páginas, componentes, providers, pipes, tabs e diretivas. E, como se não bastasse, nos fornece um processo de build bem definido, que vai compilar, otimizar e minificar nosso aplicativo (pretendo aprofundar mais em como funciona esse processo aqui no blog futuramente).

Calma, que já tá acabando. Foram adicionados novos componentes de UI que antes não existiam (como o DateTime picker). O ngCordova “evoluiu” para o Ionic Native. Existe, por padrão, uma nova ferramenta para captura de erros. Agora existe suporte aos famigerados Progressive Web Apps, dessa forma não estamos mais presos ao controle das lojas de aplicativos.

E pra finalizar: não existe mais um sistema de navegação baseado em URLs. E isso é uma coisa boa, acredite. A equipe do Ionic percebeu que um sistema de navegação baseado em URLs como o ngRoute ou o UI-Router limitavam os aplicativos a forma como as aplicações funcionam na web. E na web tudo isso faz sentido, já que dependemos das URLs para sair navegando por aí. Mas nos aplicativos isso era uma limitação, já que neles a gente não depende de URLs para navegar. Tudo o que nós precisamos é poder exibir uma página e remover essa página da pilha de navegação. Por mais que esse conceito pareça simples, ele nos trás a possibilidade de possuirmos múltiplas pilhas de navegação que compartilham das mesmas páginas e funcionam de forma independente, ficou complexo? Pretendo discorrer sobre o tema em um próximo artigo.

Conclusão

Mudou muita coisa, mas vale a pena dar uma olhada. E, se não der para migrar seus antigos aplicativos, no mínimo comece a escrever os novos usando o Ionic 2.

Existe um guia para migração que você pode encontrar clicando aqui e para mais informações sobre o lançamento oficial é só acessar o post: Announcing Ionic 2.0.0 Final.

Pretendo voltar a escrever mais aqui, ainda não sei se vou me comprometer a postar com certa regularidade (já que tentei outras vezes e fracassei miseravelmente), mas pretendo falar sobre o novo sistema de navegação, testes automatizados, integração contínua, typescript, offline first e por aí vai. Então, nos vemos em breve.

recipes

Ionic Market: Recipes Starter

Fala pessoal, beleza? Durante esse mês de janeiro eu trabalhei duro em um projeto pessoal para testar as minhas habilidades com o Ionic Framework e o resultado foi o aplicativo Mini Receitas que acabou indo parar no Featured Apps do Showcase do Ionic por alguns dias como um dos melhores aplicativos criados com o Framework.

Pois bem, é hora de seguir em frente e compartilhar mais um pouco do meu conhecimento com vocês. Acabei de lançar o código base do meu aplicativo Mini Receitas lá no Ionic Market.

Fiz esse projeto pensando muito em performance e manutenabilidade. Logo, vocês terão acesso a um aplicativo rápido, com código organizado. Além de vir com integração com plataformas como AppTentive e CodePush.

Ainda tem muitas features que desejo implementar nesse projeto, como integração com Facebook, analytics, notificações push, deeplinks, anúncios, etc. e será através do feedback da comunidade que irei me guiar dentre as tecnologias disponí­veis.

speed

Otimizando a performance de aplicativos Cordova/Ionic Framework

Olá pessoal, nessa última semana tive a boa surpresa de ter meu aplicativo Mini Receitas aceito no showcase do Ionic Framework e o melhor é que ele foi considerado pela equipe do Ionic como um dos Top Apps feitos com o framework. Esse bom resultado me fez refletir em como eles escolhem os aplicativos que vão para o Top Apps e a conclusão que eu cheguei é que como eles não conseguem testar a finalidade de todos os aplicativos até por que eles podem estar em idiomar que eles desconhecem, como o português, o que vale mesmo é a performance e o design.

Não sou nenhum especialista em design, mas depois de meia década trabalhando como front-end eu tenho noção do que não fazer, então acho que não passo vergonha como muitos desenvolvedores (principalmente os que vieram do mundo back-end). No entanto, como não sou especialista nesse assunto prefiro falar pra vocês dois cuidados (banco de dados e animações) que tomei para criar um aplicativo híbrido performático.

Banco de dados

A primeira coisa que eu fiz para otimizar a performance do aplicativo foi efetuar o mínimo de operações possíveis no banco de dados pois essas bloqueiam o DOM e iriam travar minha interface. De início segui as dicas do artigo How To Use PouchDB + SQLite For Local Storage In Your Ionic App da Ashteya Biharisingh e embora isso tenha melhorado muito a performance do meu aplicativo eu ainda tinha problemas nas transições de telas. Principalmente nos primeiros acessos às telas, pois o Ionic ainda não tinha colocado-as em cache.

O que acontece é que quando você realiza o primeiro acesso a uma página não cacheada ou uma que possui o cache desabilitado o seu código consulta o banco e isso causa o bloqueio do DOM. Então o objetivo é evitar que ocorra esse bloqueio. E a forma que encontrei de fazer isso foi carregar todo o banco de dados em cache antes mesmo do usuário acessar a tela que irá utilizá-lo.

Para isso eu criei um serviço chamado Loader que possui um método chamado done que me retorna uma promise. Esse método done é quem carrega todos os dados do banco para o cache como descrito pelo artigo da Ashteya.

Logo, o que precisei fazer (usando alguns recursos do ES6) foi:

services/loader.service.js

/**
  * LoaderService
  */
  
(function() {
  'use strict';

  function LoaderService ($q, RecipesService){
    'ngInject';

    this.done = function() {
      return $q.all([
                RecipesService.getAllRecipes()
              ])
              .then((...args) => args)
              .catch((...args) => args)
    }

  }

  module.exports = LoaderService;
}());

index.run.js

/**
  * Run
  */
  
(function() {
  'use strict';

  function runBlock (Loader, $ionicPlatform, $cordovaSplashscreen) {
    'ngInject';

    $ionicPlatform.ready(function(){
      Loader.done()
            .then(function(){
              $cordovaSplashscreen.hide();
            })
    })

  }

  module.exports = runBlock;
}());

index.module.js

/**
  * Definição do módulo
  */
  
import runBlock from './index.run';

import LoaderService from './services/loader.service';
import RecipesService from './services/recipes.service';

angular.module('miniReceitas', ['ionic', 'ngCordova'])
       .run(runBlock)

       .service('RecipesService', RecipesService)
       .service('Loader', LoaderService);

Note que eu também faço o uso do plugin cordova-plugin-splashscreen , faço isso para que o usuário só possa interagir com o aplicativo após todo o banco de dados estar em cache. Dessa forma ele não percebe o bloqueio do DOM pelas consultas ao banco. O único momento o usuário pode vir a notar algum tipo de bloqueio é ao inserir, alterar ou deletar algum registro no banco. No entanto essas operações normalmente são mais leves que uma query de consulta.

Animações

Animações são muito importantes para que aplicativo ofereçam uma boa experiência para o usuário. Quando estamos criando sites nem sempre nos preocupamos com a performance delas já que computadores possuem muito mais poder de processamento, porém nem sempre trabalhamos com mobile-first, o que é um erro em um mundo onde o usuário passa boa parte do seu dia conectado a internet através de dispositivos móveis.

Enfim, para otimizar as animações nós devemos entender como o CSS é renderizado e para isso eu recomendo a leitura do artigo Entendendo os Reflows. Mas em síntese o que precisamos fazer é evitar Repaints e Reflows. E para evitá-los basta projetar seu CSS com propriedades que não disparem esses eventos.

Você pode, por exemplo, utilizar o transform: translateY ao invés do top ou o bottom para uma animação, pois o top e bottom disparam tanto o Repaint quanto o Reflow. Você pode utilizar o CSS TRIGGERS para consultar se a propriedade css que você está utilizando para suas animações dispara algum desses eventos.

(Bônus) DOM

Ainda não terminei a implementação desse terceiro item, por isso ele está presente apenas como bônus. Mas assim como temos que ter cuidado com a árvore de renderização do CSS, nós também temos que ter cuidado com a do HTML. E uma técnica que vem cada vez mais sendo utilizada para otimizar a performance do DOM é o ato de renderizar apenas os nós visíveis. No caso do AngularJS que cada um dos nós pode possuir uma escopo ligado a ele por meio do two-way data binding isso pode otimizar ainda mais a performance pois remove os listeners dos itens que não estão visíveis, já que eles não estão renderizados.

No Ionic uma diretiva que faz uso dessa técnica é a Collection Repeat e estou trabalhando para implementá-la no novo Slider que foi introduzido na versão 1.2 do framework.

Enfim fim

E é isso, além dessas existem outras otimizações que já citei no artigo 4 Dicas para trabalhar com o Ionic Framework e vocês podem encontrar mais algumas dicas na apresentação Top 10 Performance Techniques for PhoneGap and Hybrid Apps do Christophe Coenraets que ainda continua super atual. Sem contar que no fim das contas é tudo Javascript, logo, otimizações a nível da linguagem são sempre bem vindas, nesse sentido recomendo o artigo 10 Javascript Performance Boosting Tips from Nicholas Zakas do Jon Raasch e o artigo do Addy Osmani entitulado Writing Fast, Memory-Efficient JavaScript.


Ultimamente tenho estudado mais questões relacionadas a engajamento do usuário, promoção de aplicativos e melhoria de ranking nas lojas de aplicativos e achei conveniente fazer um post sobre performance enquanto essas informações ainda estão frescas em minha memória. Espero que esse post possa ajudá-los e caso você utilize alguma outra técnica para otimizar a performance dos seus aplicativos deixe seu comentário abaixo para que possamos disctuir e criar aplicativos cada vez melhores.

tappx

Promova seu aplicativo de graça

Eu sei, o título desse post até parece sensacionalista e com o objetivo de conseguir cliques, mas, pelo menos dessa vez, não é. Nesse ano de 2016 eu me propus um desafio: viver só com a grana proveniente de meus aplicativos para dispositivos móveis e pra isso eu estabeleci que faria um aplicativo por mês até o fim do ano.

Daí você pergunta: "Ok, mas o que isso tem a ver com promoção de aplicativos gratuita?". Bom, a princípio nada, exceto que para conseguir viver disso eu preciso que os aplicativos tenham muitos downloads, porém com o grande número de aplicativos nas lojas hoje a concorrência é muito grande e provavelmente meus aplicativos não vão ganhar usuários se eu não encontrar formas de chegar até eles.

E aí que entram técnicas como ASO, que é o equivalente ao SEO para aplicativos, e os Ads, afinal, eu posso anunciar meus aplicativos. Mas aí entra um outro porém, o custo de aquisição do usuário. Enquanto o ASO é um conjunto de técnicas para melhorar o rankeamento nas lojas, na maioria das vezes não é necessário gastar dinheiro com ele. Já com os Ads a conversa muda.

O custo médio de aquisição de usuários varia bastante de acordo com inúmeros fatores, como: país, tema do aplicativo, idade do público alvo, etc.. E, infelizmente, eu não tenho muita grana pra investir, por exemplo, R$ 1,00 para cada nova instalação do aplicativo, e olha que esse é um valor relativamente baixo.

E foi aí que eu conheci o Tappx.

Tappx

O Tappx é um Ad Network para promoção de anúncios diferente das outras. Nela, a cada cliques em anúncios veiculados por ela em seu aplicativo você ganha 500 tappix, que é a moeda de troca da plataforma, com eles você pode criar suas próprias campanhas onde a cada clique que seu anúncio receber você paga 500 tappix, ou seja, para cada vez que alguém clicar em um anúncio no seu aplicativo você ganha o direito de exibir anúncios nos aplicativos de outras pessoas até que alguém clique no seu anúncio.

O interessante é que a comunidade Tappx hoje é muito forte e existem alguns aplicativos bem populares que a utilizam. Ontem, em meu primeiro teste com a plataforma, eu consegui milhares de impressões do meu anúncio em poucas horas. Infelizmente eu não tinha tappix o sufuciente para conseguir muitos cliques, mas aí entra outro fator interessante sobre a plataforma: a cada pessoa indicada por você que passar a usar a plataforma você ganha 50.000 tappix.

Ionic

O Tappx possui integração tanto para Android quanto para iOS, então se você desenvolve nativo é só baixar a SDK deles e ser feliz. No entanto, também é possível integrar com outras plataformas como Unity, Firefox OS e Cordova.

O meu novo aplicativo (Mini Receitas) foi desenvolvido em Cordova/Ionic e eu realizei a integração através do plugin Cordova Admob que inclusive já possui um módulo AngularJS para integração com aplicativos Ionic. Nesse plugin você pode configurar tanto o AdMob quanto o Tappx e ainda dividir os anúncios exibidos em seu aplicativo entre as duas plataformas.

  1. Para instalar o plugin no Ionic basta rodar o comando:
ionic plugin add cordova-admob
  1. Adicionar o seguinte código em seu index.html (note que você não precisa copiar nenhum arquivo, o plugin copiará os arquivos automaticamente na fase prepare do Cordova):
<script src="lib/angular-admob/angular-admob.js"></script>
  1. Injetar o módulo na definição do seu aplicativo:
var app = angular.module('myApp', ['admobModule']);
  1. Configurar o plugin com as suas informações do AdMob e do Tappx:
app.config(['admobSvcProvider', function (admobSvcProvider) {
    admobSvcProvider.setOptions({
        publisherId:          "ca-app-pub-XXXXXXXXXXXXXXXX/BBBBBBBBBB",  // Obrigatório
        interstitialAdId:     "ca-app-pub-XXXXXXXXXXXXXXXX/IIIIIIIIII",  // Opcional
        tappxIdiOs:           "/XXXXXXXXX/Pub-XXXX-iOS-IIII",            // Opcional
        tappxIdAndroid:       "/XXXXXXXXX/Pub-XXXX-Android-AAAA",        // Opcional
        tappxShare:           0.5                                        // Opcional
    });
}]);
  1. Exibir os anúncios (você pode fazer isso em um controller específico também):
app.run(['admobSvc', function (admobSvc) {
    admobSvc.createBannerView();
}]);

E é isso. Em um próximo post espero poder falar mais sobre ASO (App Store Optimization), ainda estou estudando e aplicando aos poucos os conhecimentos adquiridos. O meu novo aplicativo (Mini Receitas) ainda não tem muitos downloads, mas com uma plataforma de promoção gratuita as chances de eu atingir meus objetivos ao final do ano aumentam e espero que vocês também possam vir a se beneficiar da plataforma.

ionic

4 Dicas para trabalhar com o Ionic Framework

1 – AngularJS

Originalmente essa não era a primeira dica, mas no decorrer da escrita notei que provavelmente era a dica mais importante. O Ionic é um framework escrito sobre o AngularJS, logo, boa parte das dicas com relação ao AngularJS cabem no Ionic (como a últim dica).

De fato o AngularJS não é o framework SPA mais performático do mercado, ele tem problemas estruturais que remetem ao início de seu desenvolvimento e impactam na performance do mesmo e é um dos motivos da total reescrita do framework para sua segunda versão. Com o passar dos meses (e versões) a equipe do AngularJS conseguiu mitigar vários dos problemas de performance e para que você consiga extrair o máximo do Ionic Framework eu recomendo fortemente que você conheça o AngularJS, seus pontos fortes, problemas, peculiaridades, arquitetura, etc.

E para otimizar a performance de seus apps sugiro que leia a série de artigos Micro tunnings with Angular apps (Parte 1 & Parte 2) do GDE Will Mendes.

2 – Native Scrolling

Uma das grandes sacadas da equipe do Ionic para a versão 1.0 "uranium-unicorn" (eu gosto desse nome), foi a implementação do Native Scrolling, que nada mais é que o scroll padrão dos dispositivos. Mas por que isso é bom? Isso é bom por que no começo do desenvolvimento do framework a equipe optou por desenvolver o scroll em javascript para poder oferecer algumas funcionalidades que não seriam possíveis no contexto daquela época dos dispositivos móveis, como Pull To Refresh, Infinite Scrolling, List Reordering, e Collection Repeat. E, convenhamos, grande parte do sucesso do framework é por causa dessas funcionalidades e de sua facilidade de utilização.

Então os dispositivos móveis evoluíram tanto o hardware quanto o software e após o Android 4.1 (Jelly Bean) e o iOS8 essas funcionalidades se tornaram possíveis graças às atualizações do navegador nativo do Android e da WKWebView no iOS8, pois ambas as plataformas passaram a ter suporte aos eventos de scroll nativo e foi aí que a equipe do Ionic resolveu implementar o Native Scrolling, pois com ele a CPU e a GPU do dispositivo móvel, que não é tão potente quanto a de um PC, não precisará mais processar o JS Scrolling, podendo então se preocupar com o que realmente importa: sua aplicação. O que deixará seu aplicativo mais rápido e resultará numa experiência mais fluída para o usuário.

O Native Scrolling funciona da mesma forma que o atributo overflow-scroll="true" na diretiva <ion-content> e para utilizá-lo basta desabilitar o jsScrolling no ionicConfig:

angular.module('ionicApp', ['ionic']).config(function($ionicConfigProvider) {
  if(!ionic.Platform.isIOS())$ionicConfigProvider.scrolling.jsScrolling(false);
})

A diferença de performance ao utilizar o Native Scrolling é notável e se torna ainda mais perceptível em dispositivos Android. No entanto essa funcionalidade ainda não está 100%. Ela não funciona muito bem com o Keyboard e o Collection Repeat. Portanto não é receomendo que você utilize o Colection Repeat ou um input em uma tela que possua o Native Scrolling ativado.

ps.: O código acima ignora a plataforma iOS pois os eventos de scroll nativos só foram implementados na WKWebView do iOS8 e o Ionic oferece suporte ao iOS7 também, logo, o scroll nativo não funcionará como deveria em todas as versões do iOS. É recomendado o uso do scroll nativo em dipositivos iOS caso o suporte de seu aplicativo seja a partir do iOS8.

3 – Debug remoto e autoreload

Durante o desenvolvimento de uma aplicação é sempre bom possuir boas ferramentas de debug para não desenvolvermos às cegas. E no caso de Aplicativos Híbridos nós podemos contar com o apoio do browser nessa tarefa.

Basta rodar o comando ionic run android -l -c -s. Para maiores informações sobre esse comando acesse o artigo Live Reload All the Things.

4 – Estrutura de diretórios e arquivos

Uma boa estrutura de diretórios e arquivos para seu aplicativo é essencial e, de fato, a estrutura dos templates (blank, sidemenu e tabs) do Ionic não é a melhor, pois conforme sua aplicação vai crescendo fica mais complicado gerenciar todos os seus controllers em um único arquivo e quando você divide esse arquivo em um para cada controller fica complicado gerenciar quais arquivos estão relacionados.

Pensando nisso a comunidade do AngularJS criou uma recomendação, chamada Best Practice Recommendations for Angular App Structure, para facilitar no desenvolvimento de Aplicações AngularJS, segundo ela o melhor é organizar seus diretórios e arquivos por funcionalidades e páginas, um exemplo simples seria algo como:

sampleapp/
    app.css
    app.js
    app-controller.js
    app-controller_test.js
    components/
        bar/                        "bar" describes what the service does
            bar.js
            bar-service.js
            bar-service_test.js
        foo/                        "foo" describes what the directive does
            foo.js
            foo-directive.js
            foo-directive_test.js
index.html

Acredito que essas 4 dicas são essenciais para melhorar a performance e a qualidade de aplicativos criados com o Ionic. Em breve voltarei com mais dicas referentes a acesso às APIs do dispositivo, PouchDB, Sincronização com webservice REST, etc.