Une meilleure expérience utilisateur grâce au projet R&D : Decouple

expérience utilisateur
Logo Decouple

Decouple, en quête d’une alternative à l’expérience utilisateur unique

​Le développement logiciel a toujours été ralenti par des problèmes de compatibilité entre les plateformes.

Au cours des années, de nombreuses solutions ont été apportées. C’est le cas de la standardisation des bibliothèques standard (ANSI C en 1986), la création de langages interprétés de haut niveau ne dépendant pas des spécificités d’une plateforme (Python en 1991, Common Lisp en 1994), ou la création de langages de programmation basés sur des machines virtuelles pouvant s’exécuter sans recompilation sur plusieurs architectures (Java en 1996).

L’arrivée du web a sans doute eu le plus grand impact sur le développement pour plusieurs plateformes, en permettant à un site unique d’être accessible sur toutes les plateformes majeures (desktop, mobile).

En facilitant le déploiement et le partage de mises à jour, le web est devenu omniprésent.

D’un point de vue purement technique, cette convergence vers le web a largement facilité le déploiement d’applications en diminuant les différences entre les plateformes. En revanche, les attentes des utilisateurs ont continué d’évoluer sur chaque plateforme de manière indépendante. Aujourd’hui, il existe une division entre les attentes des entreprises (application unique) et celles des utilisateurs.

Dans cet article, nous explorerons les raisons pour lesquelles il est souhaitable de découpler une application de son expérience utilisateur.

Une application, plusieurs expériences

Les applications mobiles se sont toujours placées à l’opposé du développement web. Elles résistent de plusieurs manières, pour plusieurs raisons.

Pour commencer, la perte de performance liée au web est plus difficilement acceptable sur mobile. Particulièrement sur des appareils peu puissants, où le surcoût de temps d’exécution, d’utilisation de batterie, de mémoire ou l’augmentation du trafic réseau sont des raisons liées à cette réticence. Ces raisons sont principalement causées par le besoin d’interpréter du code JavaScript au lieu d’utiliser les langages compilés natifs. Les applications web sur mobile sont aussi limitées en fonctionnalité par ce que la plateforme permet de faire, par exemple, l’absence d’alternative à Safari sur iOS rend impossible l’utilisation de notifications push.

Les plateformes mobiles sont aussi caractérisées par leur différent type d’expérience utilisateur. Les développeur·euse·s doivent le prendre en compte, au risque de publier une application qui est désagréable ou difficile à utiliser. Parmis les différences notoires entre plateformes, on remarque la position du bouton de création (en bas à droite sur Android, en haut à droite sur iOS) ou le comportement de la navigation (aucune navigation nativement sur desktop, navigation “up” uniquement sur iOS, navigation “back” uniquement sur le web, à la fois “up” et “back” sur Android).

Ce phénomène est aussi visible en dehors du marché mobile, particulièrement au sein des écosystèmes Linux. Permettant une grande customisation de la part des utilisateur·trice·s, il est attendu que les applications adoptent le paramétrage et les aspects visuels du système, par exemple via GTK ou KDE.

Traditionnellement, ces demandes se traduisent par le développement de plusieurs applications, chacune axée vers une unique plateforme. Chaque application doit donc être développée trois fois : web, Android et iOS. Chaque plateforme possédant un rythme de développement et publication différent, il est fréquent de retrouver des différences de fonctionnalités. Les applications natives desktop sont souvent considérées comme trop peu impactantes pour nécessiter leur développement, particulièrement avec l’arrivée d’Electron.

Cet éloignement du natif pose des problèmes de sécurité et d’utilisation des ressources, chaque application installant une version légèrement différente d’Electron sans appliquer les corrections de sécurité. Cette multiplication des exécutables va à l’encontre du fonctionnement des systèmes d’exploitations, optimisés pour le partage de la mémoire entre processus, qui devient impossible avec Electron. Malgré ses inconvénients, cette technologie est fréquemment préférée par les entreprises, parce qu’elle diminue fortement les coûts de développement.

Même sans quitter l’environnement web, il peut être intéressant de proposer une expérience utilisateur différente au sein d’un même site, notamment dans le cas des marques blanches. Adapter l’iconographie et l’image de marque est possible nativement sur le web, mais les modifications plus profondes (structure des pages, navigation) compliquent fortement le développement de l’application.

Une expérience, plusieurs applications

À l’inverse, il peut être aussi souhaité d’utiliser la même image de marque pour plusieurs projets. Dans cette optique, il est fréquent d’extraire une bibliothèque de composants. Certaines ont pour but de faciliter la personnalisation, comme un autre projet de la R&D 4SH : Leaflock.

Ce type de bibliothèques peut rendre plus difficile les modifications d’apparence futures, parce qu’elles ont maintenant un impact plus large qu’un unique projet, qui est souvent l’unité de pilotage. La réutilisation de composants poussée à son extrême peut aussi faire disparaître l’image de marque si les différentes applications se ressemblent trop (effet Bootstrap).

Même s’il n’est pas partagé entre plusieurs applications, le design system évolue à un rythme différent du reste de l’application, parce que l’équipe de design n’est souvent pas intégrée à l’équipe de développement. Cela peut rendre difficile le développement de nouvelles fonctionnalités si certains composants n’ont pas encore été spécifiés.

Idéalement, il serait souhaitable pour l’équipe de développement d’utiliser une batterie de composants prédéfinis. Ainsi, l’équipe design pourrait modifier à souhait leur apparence pendant toute la durée de vie du projet. Elle pourrait aisément les réutiliser au sein de différents projets, ou même déployer des variantes d’une unique application dont la seule différence est l’expérience utilisateur.

Le projet Decouple, de quoi s’agit-il ?

Decouple est un projet open source (Apache 2.0) auquel 4SH participe dans le cadre de son programme de R&D. Actuellement expérimental, il vise à séparer le développement de l’application du développement de l’expérience utilisateur et de l’apparence visuelle. Il permet de commencer le développement avant la finalisation du design system, grâce à des kits de composants prêts à l’utilisation. Aussi, de modifier l’apparence de l’application et l’expérience utilisateur au sens large sans nécessiter de réécriture de l’application elle-même. Il permet également à une unique application d’être utilisée avec plusieurs design systems différents. Soit pour satisfaire des besoins clients différents, soit pour partager le code d’une application entière entre plusieurs plateformes.

Kotlin

Decouple est basé sur Kotlin, un langage de programmation moderne créé par JetBrains (IntelliJ, PyCharm, WebStorm, Android Studio), suite à leur grande expérience avec Java.

Comme Java, Kotlin possède des fonctionnalités orientées objets avancées. Mais il profite de sa syntaxe plus légère pour simplifier de nombreux patrons de conception et intégrer un support pour des idiomes de la programmation fonctionnelle, comme les opérateurs monadiques et les coroutines basées sur les continuations. Kotlin est déjà largement utilisé chez 4SH pour le développement côté serveur, mais Kotlin peut aussi satisfaire d’autres cas d’utilisation.

Kotlin peut être utilisé sur toutes les plateformes majeures. Sur desktop et côté serveur, Kotlin se base sur la JVM pour être interopérable avec l’écosystème Java, tout en profitant de ses performances. En version web, Kotlin se base sur JavaScript ou sur WebAssembly. Sur les plateformes trop peu puissantes pour exécuter une JVM (e.g. iOS, objets connectés), Kotlin se base sur LLVM pour générer des binaires natifs.

Kotlin permet d’écrire du code multiplateforme en déléguant une partie de l’implémentation à chaque plateforme. Cela permet aux développeur·euse·s d’une application d’écrire du code commun, tout en ayant la possibilité d’appeler directement les APIs natives, si l’API commune est incomplète ou insatisfaisante (ce qui est impossible avec Xamarin ou React Native). De nombreux projets existent pour créer des APIs communes pour différents aspects techniques :

  • ​Ktor (client et serveur HTTP et WebSocket),
  • Kodein (injection de dépendances),
  • Ballast (MVI), 
  • Napier (logging),
  • Arrow (programmation fonctionnelle), 
  • et beaucoup d’autres, qui couvrent tous les concepts de programmation.

Compose

Compose est un framework réactif créé par Google. Fortement inspiré par React, Compose s’affranchit de ses limites grâce au typage de Kotlin ainsi qu’à une forte intégration avec le compilateur. Associé aux coroutines, Compose fournit un modèle de programmation possédant tous les avantages des approches basées sur les flots (RxJava, RxJs, Project Reactor) tout en restant aussi lisible que du code impératif.

Avec Compose, chaque composant est une fonction annotée par `@Composable`, qui peut accepter des paramètres et retourner une valeur. Cette manière de représenter les composants permet une grande flexibilité parce qu’il n’est pas nécessaire d’apprendre une nouvelle syntaxe pour écrire une UI (JSX en React, modèles HTML en Angular), puisque l’UI est écrite en Kotlin traditionnel, utilisant toute la syntaxe normale du langage (`if`, `for`, …).

Google fournit aussi une bibliothèque de composants basés sur Compose pour Android et WearOS, qui est aujourd’hui la manière recommandée de développer de nouvelles applications.

JetBrains étend Compose en portant les composants Android vers le web (via canvas) ainsi que vers le desktop. JetBrains fournit aussi une couche de compatibilité entre la syntaxe Compose et les éléments du DOM. Cela permet donc d’utiliser Compose au sein de n’importe quelle application web traditionnelle. ​L’écosystème Compose est déjà très riche. Il est possible de créer des applications en ligne de commande grâce à Mosaic, des plugins pour IntelliJ grâce à Jewel, ou encore d’adapter des composants natifs (par exemple ceux d’iOS) grâce à Redwood. En revanche, chacune de ces bibliothèques crée sa propre surface de composants, et ne sont pas compatibles entre elles.

Découpler le kit de composants et l’application

Avec Decouple, l’implémentation des composants vit en dehors de l’application. Chaque application déclare les composants qu’elle souhaite utiliser, ainsi que l’implémentation désirée pour chacun d’entre eux (de manière programmable, de sorte que le choix peut être différent selon la plateforme ou n’importe quel autre critère métier). De cette façon, l’application ne peut pas utiliser des composants non déclarés tout en ayant la garantie que chaque composant déclaré possède une implémentation dans chaque cas demandé (vérification à la compilation).

Grâce à la standardisation des composants, il devient possible de commencer le développement en utilisant un des styles visuels fournis. Puis, de remplacer les composants petit à petit par une implémentation sur-mesure sans bloquer l’avancée des fonctionnalités. Une application peut aussi utiliser un kit de composants en remplaçant un ou plusieurs. L’application connaît donc les composants disponibles et peut s’y adapter. Par exemple, en déclarant une interface simplifiée pour créer une variante en ligne de commande.

Decouple ajoute aussi des concepts par-dessus chaque implémentation, comme la gestion implicite des temps de chargement au sein de tous les composants (affichée différemment selon l’implémentation).

L’équipe de développement peut donc raisonner sur les fonctionnalités sans dépendre d’une implémentation spécifique de l’UI.

Test de comportement d’UI

Par définition, il n’est pas possible de réaliser des tests graphiques qui soient agnostiques de l’apparence visuelle. En revanche, puisque tout le code de l’application est écrit en termes de composants Decouple, il est possible de substituer une fausse implémentation dédiée aux tests. Cette implémentation est fournie au sein du projet. Elle permet de réaliser des tests sur la structure, les données et les interactions de l’UI, sans être impactée par les différences entre plateformes.

Cette implémentation des tests n’est pas susceptible à la plus grande faiblesse des tests d’UI traditionnels : leur tendance devrait être réécrits lors de chaque modification du design system. Il devient donc possible de tester la cohérence des données et des événements : il s’agit donc de tests unitaires d’UI. De plus, puisqu’aucune UI réelle n’est exécutée, les tests sont bien plus rapides, ce qui améliore fortement l’expérience de développement.

Cette représentation entièrement sémantique d’une UI ouvre aussi la porte vers des manières alternatives d’interagir avec une application, comme leur utilisation pour améliorer des outils d’accessibilité.

Enjeux

La difficulté principale du projet Decouple est de fournir une bibliothèque de composants, qui soit à la fois suffisamment variée pour couvrir la majorité des cas d’utilisation (l’utilisateur aura toujours la possibilité d’ajouter ses propres composants pour combler les cas particuliers), mais aussi suffisamment flexible pour pouvoir être implémentée sur des designs systems variés de manière naturelle.

La participation de la R&D 4SH va permettre de lancer une discussion multidisciplinaire sur ces sujets, en s’appuyant sur notre expérience de créateurs de solutions métier, ainsi que sur les compétences de nos UX designers. L’objectif étant de créer une API qui serve d’intermédiaire entre les équipes design et les équipes techniques.

Pour en apprendre plus sur le projet, vous pouvez nous contacter par la chaîne #decouple sur le Slack officiel de Kotlin, ou lire la documentation du projet (en anglais) : dépôt, FAQ et documentation.

Restez connecté·e·s pour la suite…

%d blogueurs aiment cette page :