News

Étude de cas JetBrains Toolbox App : Migration d’un million d’utilisateurs vers Kotlin et Compose Multiplatform

Read this post in other languages:

Victor Kropp, chef d’équipe Toolbox App chez JetBrains, raconte le passage de Kotlin et de Compose Multiplatform sur ordinateurs de bureau.

L’application JetBrains Toolbox App constitue le point d’entrée unique pour développer avec les IDE de JetBrains. Elle sert de panneau de commande pour les outils et les projets, et rend l’installation et la mise à jour des IDE JetBrains plus simple et rapide. Lancée en 2015 en tant que projet de hackathon, l’application compte désormais un million d’utilisateurs actifs par mois et renforce leur productivité avec les produits JetBrains.

L’équipe Toolbox App a migré son application de C++ et JavaScript vers Kotlin et Compose Multiplatform avec succès et a ainsi rendu son code plus facile maintenir et utiliser tout en livrant des artefacts plus petits et avec de meilleures performances d’exécution.

Pour en savoir plus, lisez ce qui suit ou écoutez le témoignage de Victor Kropp, Responsable de l’équipe Toolbox App chez JetBrains, dans le podcast Talking Kotlin n°107.

Victor, pouvez-vous présenter l’architecture et la pile technologique utilisées par JetBrains Toolbox App ?

Toolbox App est une application client-serveur type. L’application de bureau demande une liste des outils disponibles au serveur, la montre à l’utilisateur et télécharge les mises à jour des produits JetBrains si nécessaire. Nous avons implémenté la partie côté serveur de notre application en Kotlin dès le début. Mais pour l’application de bureau, c’était une autre histoire.

Lorsque nous avons commencé à créer l’application de bureau pour JetBrains Toolbox App en 2015, nous avons utilisé C++ pour implémenter sa logique métier et Chromium Embedded Framework avec React et HTML/CSS/JS pour créer l’interface utilisateur. Nous avons fait ce choix à une époque où Kotlin 1.0 n’était pas encore sorti, pas plus que le JDK modulaire qui est arrivé avec Java 9. Nous ne pouvions pas nous permettre d’avoir un environnement d’exécution Java pesant des centaines de mégaoctets pour une petite application utilitaire et ne voulions pas obliger nos utilisateurs à configurer leur environnement manuellement. Nous avons donc choisi une approche radicalement différente.

En 2021, nous sommes finalement passés en 100 % Kotlin en migrant l’interface utilisateur de React vers Compose Multiplatform, plus précisément Compose for Desktop.

Visitez le site web de Compose for Desktop

Comment utilisez-vous Kotlin et ses bibliothèques dans votre produit ?

La migration vers Kotlin étant terminée, nous l’utilisons partout. Outre Compose for Desktop pour l’interface utilisateur, nous faisons un usage intensif des kotlinx.coroutines pour tous les jobs asynchrones. Toolbox App manipule beaucoup d’objets JSON, nous utilisons donc naturellement kotlinx.serialization pour la (dé)sérialisation.

Nous avons fait en sorte que le côté serveur reste aussi simple que possible. En fait, il ne s’agit pas d’un serveur HTTP comme on pourrait l’imaginer. Toutes les informations et les descriptions des outils installables (appelés « feeds » dans Toolbox App) sont générées de manière statique et fournies sous forme de fichiers JSON à partir du CDN. Comme ils ne changent pas souvent, nous les mettons à jour uniquement lorsque la nouvelle version d’un outil est publiée dans le cadre du pipeline de livraison continue sur TeamCity. Le générateur est un simple programme Kotlin en ligne de commande, qui est appelé en tant que « configuration de build » (nom donné par TeamCity à un job) et se déclenche automatiquement à chaque build des produits pris en charge. Un second job fusionne ensuite périodiquement tous les feeds nouvellement générés, élimine les feeds obsolètes et effectue la validation.

Pourquoi l’équipe Toolbox App a-t-elle décidé d’utiliser Kotlin pour le développement de l’application de bureau ?

Avant de migrer vers Compose for Desktop, nous utilisions Chromium Embedded Framework pour générer l’interface utilisateur de Toolbox App, et l’utilisation de C++ en natif pour notre logique métier facilitait la compatibilité avec les principaux systèmes d’exploitation d’ordinateurs de bureau. Les choses ont bien changé depuis et nous avons pris la décision de migrer toute la logique métier en C++ vers Kotlin sur la JVM en 2020.

En 2015, c’étaient d’excellents choix pour lancer le projet ! Nous pouvions réutiliser les composants de Ring UI, une bibliothèque de composants d’interface utilisateur web créée par JetBrains. Et nous pouvions également une grande expérience du développement web et du travail avec React.

Toutefois, ces choix présentaient aussi des inconvénients :

  • Le Chromium Embedded Framework est connu pour sa consommation de ressources. Même en veille, JetBrains Toolbox App utilisait au moins 200 Mio de RAM. Nous ne pouvions pas non plus décharger l’ensemble du framework lorsque la fenêtre était invisible, car cela aurait entraîné un délai de plusieurs secondes pour toute interaction avec l’application.
  • Nous avions besoin d’une architecture client-serveur complète dans une seule application de bureau. L’interface utilisateur web intégrée et la logique métier avaient été écrites dans des langages différents et par des personnes différentes. Cela compliquait le processus de développement et obligeait les ressources à envoyer des mégaoctets de JSON dans les deux sens à l’intérieur de l’application, en utilisant les ressources du processeur pour la (dé)sérialisation de données déjà présentes.

Après le passage de notre application en 100 % Kotlin, la situation s’est nettement améliorée :

  • Compose for Desktop est désormais beaucoup moins gourmand en ressources. Le framework Compose offre de meilleures performances d’exécution par rapport à notre implémentation JavaScript et a permis de réduire considérablement la RAM utilisée par l’application lors de l’exécution inactive en arrière-plan.
  • L’utilisation d’un langage unique permet à chaque développeur de pouvoir créer une fonctionnalité du début à la fin sans avoir à changer de contexte. Le développement est plus rapide, moins sujet aux erreurs, et le partage des connaissances entre les développeurs s’en trouve amélioré. L’ensemble de l’application utilise la même représentation pour les données en mémoire, ce qui évite les étapes supplémentaires de (dé)sérialisation.

Pouvez-vous partager votre expérience concernant l’introduction de Kotlin dans Toolbox App ?

Nous avons été confrontés à de nombreux défis. Tout d’abord, nous devions migrer une base de code vieille de cinq ans, avec toutes ses fonctionnalités et ses particularités, vers une pile différente. Pour garantir le bon fonctionnement du noyau de notre application, nous avons migré tous nos tests unitaires. Notre application requiert toutefois de nombreuses dépendances externes, qui varient évidemment selon les écosystèmes. Certaines parties dysfonctionnelles dans l’implémentation précédente ont commencé à fonctionner dans la nouvelle sans aucune autre action de notre part, simplement parce que la nouvelle dépendance les prenait en charge. A l’inverse, d’autres composants que nous tenions pour acquis ont cessé de fonctionner. Dans certains cas, nous n’avons eu connaissance de ces différences qu’après la publication. Les différents aspects de l’intégration d’un système d’exploitation illustrent ces deux cas de figure, avec par exemple l’icône de la barre d’état système (menubar) ou les serveurs proxy et les certificats SSL. D’autre part, nous avons pu réutiliser le code Kotlin écrit par d’autres équipes de JetBrains, comme le code qui régit la recherche de projets dans IntelliJ IDEA, réutilisé dans l’onglet « Projets » de Toolbox App, ou la détection de configurations spécifiques de Toolbox App utilisées par les entreprises.

Nous avons commencé à utiliser Compose for Desktop avant même qu’il ne soit annoncé publiquement et avons donc souvent été les premiers à rencontrer les problèmes qui se posaient avec le framework. En tant que pionniers de Compose for Desktop, nous avons constaté toutes sortes de problèmes à nos débuts, et nous les avons tous signalés à nos collègues de l’équipe Compose Multiplatform. L’équipe s’est montrée très efficace et réactive, et tous les problèmes ont été réglés très rapidement. Nous avons parfois pu obtenir une nouvelle version avec un correctif le jour-même… Très impressionnant ! Ils nous ont également beaucoup aidé lors de l’adoption de Compose et dans les cas où nous avions des difficultés avec le framework.

Nous avons pu réaliser un clone complet de notre design précédent. À première vue, Compose offre moins de primitives de mise en page que ce que nous avions en HTML/CSS, mais il est rapidement apparu que de simples empilements horizontaux et verticaux (Row et Column dans Compose) couvraient déjà 99 % de tous nos besoins. Lorsque nous avons commencé, il manquait encore quelques éléments à Compose for Desktop, comme la prise en charge des graphiques SVG, mais nos collègues de l’équipe Compose nous ont aidés à couvrir ces besoins très rapidement.

Au départ, nous avons utilisé les composants matériels de Compose dans toute l’application. Ces composants sont très bien pensés, mais ils ciblent essentiellement les interfaces tactiles. Les éléments ont de marges importantes (afin de pouvoir les activer facilement avec le doigt), n’ont pas d’états de survol (étant donné qu’il n’y en a pas sur les écrans tactiles) et ont un retour visuel tactile très visible. Or sur un ordinateur de bureau, les composants réagissent lorsqu’ils sont survolés et le retour visuel pour les clics ne concerne que l’élément en cours (car il n’est pas couvert par un doigt). Nous avons donc remplacé les composants matériels par les nôtres, qui fonctionnent mieux sur ordinateur de bureau. Nous prévoyons également de donner libre accès à notre bibliothèque de composants à l’avenir, alors restez à l’écoute.

Avant de choisir Compose for Desktop, avez-vous envisagé d’utiliser d’autres frameworks d’interface utilisateur ?

Une alternative aurait été de convertir l’application en une interface entièrement native, mais cela aurait demandé trois fois plus d’efforts pour chaque fonctionnalité. Nous voulions quelque chose de multiplateforme, esthétique et parfaitement compatible avec Kotlin.

Nous avons estimé que Swing était trop vieux et que l’utilisation de JavaFX n’était pas suffisamment répandue. C’est pourquoi nous avons finalement opté pour Compose for Desktop, même s’i venait tout juste de sortir à l’époque. L’assistance directe de la part de l’équipe et la boucle de rétroaction étroite se sont également avérés être de gros avantages.

Quels sont les principaux avantages que Kotlin a apportés à votre produit ?

Kotlin a considérablement simplifié notre travail au quotidien. Nous utilisons le même langage pour l’ensemble de l’application, ce qui permet aux développeurs de notre équipe de partager le code et les connaissances beaucoup plus facilement qu’auparavant. Nous avons également beaucoup plus de plaisir à écrire en Kotlin plutôt qu’en C++ et en JavaScript !

Avez-vous des conseils ou des recommandations pour nos lecteurs ?

Si vous décidez de changer de framework pour une application existante, ne sous-estimez pas la complexité de la migration. C’est presque comme d’écrire une nouvelle application à partir de zéro ! Vous devrez inévitablement réimplémenter non seulement les fonctionnalités, mais aussi toutes les petites nuances dans le comportement de votre application, qu’elles soient intentionnelles ou non.

Je crois fermement que Compose for Desktop est la solution idéale pour créer des applications multiplateforme pour ordinateurs de bureau. Par rapport aux technologies similaires, Kotlin donne accès à un écosystème éprouvé sur la JVM, son adoption est bien plus importante que celle de Dart et Flutter, et il est bien plus efficace qu’Electron avec React/JS.

Créez votre première application de bureau avec Compose for Desktop

Victor Kropp est Responsable de l’équipe JetBrains Toolbox App.

Auteur de l’article original en anglais :

image description

Discover more