jQueryMobile et PhoneGap : un duo gagnant pour vos applications mobiles ?

Le succès des smartphones, tablettes, et autres mobile devices ne semble, malgré la crise, subir aucun ralentissement : sur 2011 on observe une augmentation des ventes de smartphones de 74% et un total de 63 millions de tablettes vendues. Pour nos clients, cela déclenche une remise en perspective de leur stratégie : “comment proposer mes services mobiles à la population la plus large possible”, “comment m’adapter aux nouveaux canaux de diffusion que sont les App Store et Google Play” ou encore “puis-je maitriser mes coûts de développement et de maintenance sur ces X plateformes”.

Dans cet article, je vais essayer de vous présenter l’approche que j’ai utilisé pour un client. Je ne peux malheureusement pas rentrer dans les détails de ce projet mais sachez cependant que l’approche de développement “hybride” retenue (i.e. application mixte native / web) était un pré-requis du client… Étant plutôt un habitué des développements natifs, j’ai profité de ce projet pour essayer de me forger ma propre opinion. Je vous propose donc dans cet article d’évaluer ce que propose les technologies web pour l’implémentation d’application mobile et bien sûr, leurs limites.

jQueryMobile, les composants graphiques

jQueryMobile est un framework qui permet, à partir de pages HTML5/CSS3, d’obtenir des écrans et des composants graphiques adaptés au rendu sur un écran de smartphone ou tablette.

Il s’agit d’un framework qui se base, évidemment, sur jQuery mais utilise plus particulièrement son cousin jQuery UI pour l’implémentation des composants graphiques (widgets). Il est conçu pour fonctionner sur un grand nombre de navigateurs et de plateformes différentes : chaque plateforme est classée suivant son niveau de support ainsi il est possible de “dégrader” correctement l’application sur un ancien téléphone. Dans la même philosophie que jQuery, il essaye d’être le moins intrusif possible : les pages HTML5 contiennent seulement des attributs HTML5 “data” qui permettent de déclencher le rendu des widgets (la page est alors dite “augmentée”).

Exemple “quick & dirty”

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title></title>
  </head>
  <body>
    <p>
      [...]
    </p>
    <div data-role="page" data-theme="b" id="page1">
      <div data-role="header">
        <h3>
          Application XXX
        </h3>
      </div>
      <div data-role="content">
        <h2>
          Page 1
        </h2>
        <ul data-role="listview" data-divider-theme="a" data-inset="true">
          <li data-role="list-divider" role="heading">Menu
          </li>
          <li data-theme="c">
            <a href="#page2" data-transition="slide">Vers Page 2</a>
          </li>
          <li data-theme="c">
            <a href="#page3" data-transition="slide">Vers Page 3</a>
          </li>
          <li data-theme="c">
            <a href="#page4" data-transition="slide">Vers Page 4</a>
          </li>
        </ul>
      </div>
    </div>
    <div data-role="page" data-theme="b" id="page2">
      <div data-role="header">
        <a data-role="button" data-direction="reverse" data-rel="back" data-transition="fade" href="#page1" data-icon="arrow-l" data-iconpos="left">Retour</a>
        <h3>
          Application XXX
        </h3>
      </div>
      <div data-role="content">
        <h2>
          Page 2
        </h2><img src="https://maps.googleapis.com/maps/api/staticmap">
      </div>
    </div>
  </body>
</html>


Comme on peut le voir dans le code ci-dessus, deux DIV portent des attributs “data” qui sont découverts par jQueryMobile. “data-role=page” permet d’indiquer qu’il s’agit d’un écran et “data-theme=b” permet de choisir la charte graphique à utiliser (sachant qu’il dispose de 5 thèmes par défaut). Chaque écran peut-être composé de trois zones : header, content, footer (attribut data-role également) dans lesquels on ajoute ses composants graphiques. Pour ajouter une liste ? Il suffit d’utiliser le tag HTML <ul/> avec un attribut “data-role=listview“.

Cinématique des écrans

Ce framework est conçu pour être utilisé à la fois sur des sites web mobiles (ou finalement jQueryMobile peut-être vu comme une couche de rendu spécifique) mais également sur des applications hybrides (c-a-d installées sur le smartphone). Les pages HTML sont alors être distribuées avec l’application (on parle de pages locales) ou bien téléchargées via AJAX (pages distantes).

Afin de gérer les liens et les formulaires, jQM utilise une approche Hijax : il va ajouter, si cela est possible, un appel Ajax sur l’ensemble des liens <a href/> pour charger le fragment de page et l’injecter de façon dynamique dans l’arbre DOM. Il déclenche des animations CSS3 afin de proposer une transition adaptée.

Il est également possible de capturer des événements “spécifiques mobile” : swipe, orientationchange, tap, taphold, scroll, etc…

Retour d’expérience

Les points forts sont :

  • Le développement utilise des standards HTML5/CSS3 (et demande donc des compétences plus faciles à trouver sur le marché du travail)
  • Cela s’intègre très bien dans un développement MVC classique : il suffit que le serveur génère directement les pages dans le bon format HTML5 et ca marche tout seul
  • Les composants graphiques par défaut sont plutôt étoffés (tableau, formulaire, liste dépliables, boutons, icône, layout grid)
  • Le système de thèmes et l’outil Theme Roller permettent de créer facilement une charte graphique sans – presque – faire de CSS
  • Un développeur connaissant jQuery UI pourra assez facilement faire ses propres composants graphiques

Les points faibles (qui ne sont pas tous spécifique à jQM, mais plutôt à l’approche HTML5) :

  • L’expérience utilisateur (“User eXperience” comme on dit) est vraiment pauvre par rapport à ce qu’on peut obtenir avec une application native
  • Les performances sont mauvaises, notamment sur les transitions entre écrans sur Android
  • On subit les bugs des différentes versions de WebKit (nous avons eu des problèmes avec Android 2.1 par exemple) et finalement on retrouve les mêmes problématiques qu’avec un développement web classique : debug pas spécialement évident, même s’il existe des outils

PhoneGap et sa galaxie

PhoneGap est un framework qui permet d’encapsuler (on parle aussi de “wrapper”) une application HTML/CSS dans une application native (c-a-d disponible sur les différents Store/Market et visible dans le menu du téléphone). L’application native n’est alors qu’une coquille vide qui permet juste de masquer à l’utilisateur qu’il s’agit de simple pages web.

Suite au rachat de Nitobi (société à l’origine de PhoneGap) par Adobe, le code source de PhoneGap a été reversé à la fondation Apache via le projet Callback Cordova. Après quelques petits accrochages avec le PMC de la fondation sur l’utilisation de Git (PhoneGap étant utilisateur de Git, le projet ne souhaitait pas revenir à SVN :), il semblerait que l’incubation du projet soit sur les rails pour une acceptation comme “Top Level Project“.

Concrètement, il utilise les composants navigateurs (appelé « WebView ») disponibles sur chaque OS mobile et expose – dans ce composant navigateur – un certain nombre de passerelles vers les éléments natifs du téléphone. Évidemment, ces passerelles sont accessibles via le langage Javascript (et plus particulièrement via des flux JSON). Il devient ainsi possible depuis son application HTML/CSS/JS de piloter les éléments physiques du téléphone : caméra, fichiers, liste des contacts.

Contrairement à jQueryMobile, je ne vous ferais pas l’affront de vous présenter un projet d’exemple : la page Get Started du site de PhoneGap est très claire et permet de créer un projet en quelques secondes.

Plug-in : JS/Natif

Tous les plugins PhoneGap sont constitués d’une classe Javascript qui expose la fonctionnalité dans l’application HTML/JS (boîte rouge dans la figure ci-contre). La classe JavaScript (boîte verte dans la figure ci-contre) communique à la couche native grâce à la classe de base en utilisant PhoneGap PhoneGap.exec(). La passerelle native de PhoneGap invoque ensuite le code natif du plugin (boîte de violet dans la figure ci-contre).

La liste des plugins fournit dans le paquet par défaut de PhoneGap est la suivante :

  • Accelerometer : écouter le capteur de mouvement
  • Camera : capturer une photo via l’application dédiée
  • Capture : capturer les flux son/image/vidéo du téléphone
  • Compass : orientation magnétique (N/S/E/O) de l’appareil
  • Connection : informations sur la connectivité DATA
  • Contacts : accès à la base de contacts
  • Device : identifiant du smartphone
  • Events : accès aux événements natifs (batterylow, volumeupbutton)
  • File : lecture / écriture de fichiers
  • Geolocation : réception des coordonnées géographiques
  • Media : lecture de fichier audio
  • Notification : notifications visuelles, sonores et tactiles
  • Storage : accès à une base de données SQL

En plus des plugins gérés directement par le projet PhoneGap, il existe un certain nombre de plugins développés par la communauté sur le site GitHub dédié.

Retour d’expérience

Les points forts de PhoneGap sont :

  • Bonne intégration avec jQueryMobile
  • Permet de rapidement obtenir une application fonctionnelle et déployable sur les Market. Il existe même un système de build automatisé qui permet d’obtenir son application packagée pour les différents OS sans installer un seul SDK (c’est une offre payante proposée par Nitobi)
  • Les plugins fournis en standard permettent de répondre à 80% du besoin pour des applications catalogues/consultation

Les points faibles :

  • Il ne s’agit “que” d’une API Javascript : l’implémentation des méthodes de callback est une charge non-négligeable
  • Il faut bien prendre en compte que si on développe des plugins spécifiques PhoneGap il faudra effectuer ce développement sur chaque plateforme cible (pour la partie native ET la partie Javascript). Seule “l’API” exposée par les méthodes Javascript reste stable entre plateformes, non pas le coeur de PhoneGap.
  • Le niveau de qualité des plugins, notamment de la communauté, est très hétérogène
  • Assez compliqué de faire une application vraiment “offline” : il faut alors utiliser manuellement le localStorage HTML5 + gérer de la synchronisation avec le serveur ensuite + traiter les erreurs JSON/Ajax. Je n’ai pas eu le temps de tester des outils comme OpenMobster pour gérer la synchronisation, mais cela s’annonce prometteur.

Pour quels projets ?

Cette approche “un seul code pour l’ensemble de plateformes” limite le support des fonctionnalités au plus petit dénominateur commun. Il faut donc que le client soit conscient d’obtenir une application juste “moyenne” sur plusieurs plateformes (ie. au total sept OS sont supportés par PhoneGap) plutôt qu’une “très bonne” sur un périmètre plus réduit comme Android et iOS (quand même 70% de part de marché à eux deux). Ce n’est pas un drame mais il ne faut surtout pas s’imaginer que cela répond à 100% des besoins (ou faire imaginer cela au client :).

Je prendrais juste trois exemples pour illustrer quelques limites :

  • L’avantage évident des solutions hybride est de réduire les coûts de développement mais il ne faut pas oublier les coûts de maintenance : le développement hybride ne permet pas de réduire le périmètre de tests. D’autre part, le code étant partagé, une correction de bug devra être testée sur toutes les plateformes pour s’assurer de l’absence de régression
  • La comparaison entre les Android Design Guidelines et les iOS Mobile HIG Guidelines permet d’identifier que les approches proposées par ces deux plateformes différents parfois radicalement. Proposer une IHM identique pour ses deux plateformes ne pourra logiquement se solder que par un écart entre l’ergonomie de l’application “hydride” et des autres applications de l’OS
  • Il n’est pas possible d’utiliser des services en tache de fond : une fois le composant navigateur fermé, l’application n’existe simplement plus. Il est donc impossible de proposer du push, de synchronisation en tache de fond ou des traitements en parallèles. La norme JavaScript WebWorkers permet théoriquement de lancer plusieurs traitements en parallèle, mais n’est pas supportée par Android

Il faut donc le dire clairement, l’approche proposée par le couple jQueryMobile / PhoneGap même si elle semble sexy n’est pas applicable à n’importe quel projet mobile et il faudra réfléchir au cas par cas pour s’assurer que la technologie employée permet de répondre dans le temps et le budget envisagé par le client.

TwitterFacebookGoogle+LinkedIn
  • Stéphane

    Il est tout à fait possible de faire du push avec phonegap, il suffit de le faire en natif, comme n’importe qu’elle application !

    Sinon très bon article :)

    • http://www.drazzib.com/ Damien Raude-Morvan

      Bonjour Stéphane,

      En effet, il est possible d’utiliser du push (ou d’ailleurs n’importe quel autre type de composant) mais, comme tu le signale, c’est au prix d’un développement natif. Il faut donc le réaliser sur chaque plateforme cible (en gros sur iOS, Android et BB) et comme le cycle de vie de l’application PhoneGap (HTML/JS) est limité à son exécution graphique, il faut aussi implémenter nativement tout ou partie du traitement du flux envoyé par push.

      Bilan, on déplacement encore un peu plus le curseur en direction d’une application native et je note simplement que ça limite beaucoup l’intérêt d’une approche de type PhoneGap.

      Merci sinon ;)

  • Romain Durand

    pour avoir testé de réaliser une application utilisant jquerymobile et phonegap, je peux dire que la couche graphique utilisée (jquery mobile) manque de performances, et induit des délais de 100 a 300ms entre l’action utilisateur et le feedback, ce qui est très perturbant, notamment quand on scrolle à travers une liste …

    je me tourne vers Sencha Touch 2, qui, si plus difficile à aborder, n’a pas du tout ce problème de performance : pour preuve, comparer les 2 applis de test :
    https://play.google.com/store/apps/details?id=com.segopecelus.senchahttps://play.google.com/store/apps/details?id=com.segopecelus.jquerymobile 

  • Emmanuel REMY

    Très belle présentation de ce duo, complète. Petite remarque, l’exemple de la page est en HTML5 mais tu as mis un DOCTYPE HTML4. Je prendrai le contre-pied et me ferai l’avocat du diable sur quelques arguments: quel intérêt de devoir apprendre (par exemple) un Objective-C qui ne sert que sur Mac OS pour afficher dans 90% des applications uniquement des boites de texte et des listes déroulantes ? Les limitations actuelles que tu soulignes ont déjà leurs pendants en plugins natifs, et pour les aspect graphiques on dispose du canvas HTML5 qui permet de faire à peu prêt tout et n’importe quoi (des jeux existent déjà), même si les performances ne sont pas toujours au rendez-vous… pour le moment (mais on est en bonne voie: le canvas iOS5 est environ 7x plus performant que celui d’iOS4). Pourquoi vouloir faire des applications qui se calent à tout prix sur l’ergonomie de l’OS, alors qu’on peut imaginer une application avec une ergonomie originale qui reste la même sur toutes les plate-formes (voir par exemple l’application de Eurosport) ? En terme de gestion de projet, n’est il pas plus facile de mutualiser toutes les ressources en javascript et ainsi en tirer profit lors de changement de modèles, plutôt qu’avoir à gérer autant de projets confinés chacun avec ses problèmes spécifiques liés à l’OS et à son langage ? Je te suis complètement sur les corrections de bugs qui impactent toutes les plateformes, c’est certainement un gros inconvénient; mais d’un autre côté, quand tu fais une amélioration/correction ou quand tu proposes une nouvelle fonctionnalité, tu la publies directement pour toutes les plateformes…alors que dans le cas du développement natif chaque équipe dédiée à une plateforme doit réaliser le travail avant qu’on puisse publier pour l’ensemble des plateformes cibles (ou alors on publie avant, mais l’application n’a plus les mêmes fonctionnalités selon les OS). Et ça, ça coûte cher à une entreprise.

    Enfin, concernant Phonegap, il n’existe pas beaucoup d’équivalent. Mais concernant jQuery Mobile, il existe au moins une grosse dizaine de frameworks qui font le job. jQuery n’est pas une norme, on a trop tendance à l’oublier.

    Alors oui c’est sûr une application native restera toujours plus séduisante, et sécurisante d’un point de vue limitations possibles, mais les applications mobiles en Javascript n’en sont qu’à leurs débuts. En débordant un peu sur le sujet, l’offensive de Mozilla avec Boot to Gecko et leur achat en vue de Mootools sont des signaux forts. A suivre…

  • djamel

    djamel
    bonjour je voudrai developpez une application native avec jquery mobile et phonegape mais je n’ai aucune idée sur phonegape svp comment fair?