Ionic : Performances sur Android 4.1+, Crosswalk à la rescousse

Crosswalk: Jelly Bean & KitKat

Les développeurs d'application Cordova ne le savent que trop bien : les performances de la webview sur Android 4+ (Jelly Bean & Kit Kat) sont vraiment médiocres. De surcroît, il existe des différences notables de compatibilité (JS) et affichage (CSS) entre chaque version du système.


Mise à jour du 14/11/2017 : cordova-android 6.4.0, publié hier, n'est plus compatible avec Crosswalk. Il est donc impératif de se cantonner (au maximum) à la version 6.3.0 pour profiter de Crosswalk dans vos builds Android.

Le principe

Crosswalk se définit comme un runtime d'applications HTML (au sens large : JavaScript et CSS sont évidemment inclus). L'idée étant de :

  • Permettre l'extension des API déjà proposées par le navigateur système et y ajouter (entre autres) des fonctionnalités expérimentales.
  • S'assurer de l'uniformité du rendu de l'application, indépendamment de la plateforme utilisée.

Pour ce faire, le projet exploite Blink, le moteur de rendu de Chromium. Désormais en maintenance, la dernière version (Crosswalk Project 23) correspond à Chromium 53. Sachant que la webview embarquée dans Android 4.4 correspond à Chrome (Android) 30.
L'ajout de Crosswalk à une application Android implique un APK plus volumineux (~ +17MB) et une consommation de mémoire vive accrue (~ +30MB). Cependant, ces deux inconvénients sont effacés par les gains en performance et fidélité du rendu, ainsi que par l'ajout des dernières (ou presque) API de JavaScript et propriétés de CSS3+. C'est subjectif, je sais.

Notre but est le suivant : inclure Crosswalk seulement pour les appareils utilisant Android 4.1, 4.2, 4.3 et 4.4.

Installation

Il faut d'abord installer le plugin Cordova permettant d'embarquer Crosswalk dans le bundle de l'application :

$ cordova plugin add cordova-plugin-crosswalk-webview

Il est ensuite possible de construire un APK à destination du Play Store :

$ cordova build --release

Le dossier de sortie par défaut contiendra deux APK au lieu d'un : un par architecture (x86 et ARM). Ces APK seront destinés aux utilisateurs d'Android 4.1 à 4.4.

Pour permettre aux utilisateurs d'Android 5.0+ d'installer une application sans Crosswalk, on doit supprimer le plugin (ou utiliser une autre chaîne de compilation...) et lancer une build avec le paramètre minSdkVersion :

$ cordova build --release -- --minSdkVersion=21

Pour rappel, l'API 21 correspond à Android Lollipop 5.0.

On se retrouve ainsi avec un APK intégrant Crosswalk (le plus lourd) et un APK "standard" (qui utilisera la webview du système).

Déploiement

Sur le Play Store, il est assez aisé de distribuer plusieurs APK pour une même application. Mais comment s'assurer que les utilisateurs d'appareils récents (Android 5+) récupèrent l'application sans Crosswalk, et les autres, celle avec Crosswalk ?

Multiples APKs

L'astuce est très simple : le Play Store sélectionne systématiquement la version compatible avec le Code le plus élevé. Ainsi, il faut veiller à :

  • Spécifier les versions de SDK minimales visées pour chaque build (--minSdkVersion=21), ce qui nous garantit que les appareils sur Android 4.1 à 4.4 ne pourront pas télécharger la version Sans Crosswalk (3323). La minSdkVersion utilisée par défaut par Crosswalk est 16, inutile donc de la préciser soi-même.
  • S'assurer que la build Sans Crosswalk (3323) ait un Code de version plus élevé que celle Avec Crosswalk (3322), afin qu'elle soit téléchargée par les appareils sur Android 5+. En effet, les deux builds sont compatibles avec ces derniers (Niveau minimal d'API requis : 16).

Le code de version est à préciser dans config.xml, attribut android-versionCode de la balise <widget>.

En ce qui me concerne, aucune différence majeure n'a été remarquée entre les builds utilisant Crosswalk (Android 4.1 à 4.4) et celles utilisant la webview du système (Android 5+). Par contre, Crosswalk a permis l'utilisation (sans gêne !) des animations CSS3, de WebRTC, et de beaucoup d'autres fonctionnalités, sur des appareils parfois très vieux.