L'obsession du démarrage à froid
Le démarrage à froid est la première impression qu’une application donne à son utilisateur. Si elle met plus d’une seconde à devenir utilisable, nous avons déjà donné à l’utilisateur l’impression qu’il s’agit d’une application lente, quelle que soit la rapidité avec laquelle elle fonctionnera par la suite.
C'est aussi le moment que les utilisateurs vivent le plus souvent. Une application de suivi des habitudes est ouverte pendant quelques secondes pour cocher une case. Une application de suivi des migraines est ouverte lorsqu'une personne ne se sent pas bien et souhaite noter rapidement son état. Pour ce type d'applications, le lancement n'est pas un simple prélude à l'expérience : il constitue l'essentiel de celle-ci.
Notre objectif
Notre objectif est de moins de 600 ms De l’appui sur une icône à l’interface utilisateur interactive sur un iPhone vieux de cinq ans. Et cela, une fois que le système d’exploitation a chargé le fichier binaire, alloué de la mémoire et mis le thread principal à notre disposition. Tout ce qui se passe entre ce transfert et la première image relève de notre responsabilité.
“Le mot clé, c’est ” interactif ». Un écran de démarrage qui s’affiche instantanément puis reste figé ne compte pas. Pas plus qu’une première image remplie d’éléments de remplissage qui se réorganisent quelques instants plus tard. L’objectif, c’est le moment où l’on peut appuyer sur ce que l’on est venu chercher et où cela réagit.
Nous effectuons les mesures sur l'ancien appareil, et non sur le nouveau, pour la même raison qui nous pousse à effectuer ces tests : le téléphone le plus récent masquera pratiquement toutes les erreurs.
Ce que cela impose
Atteindre ce chiffre met rapidement fin à bien de discussions. Le réseautage n’est pas possible pendant la phase de lancement. Les SDK tiers sont difficiles à faire accepter : la plupart d’entre eux génèrent des tâches en arrière-plan avant application(_:didFinishLaunching…) même les résultats. Les caches d'images se chargent de manière différée. Les migrations de base de données s'exécutent dans une file d'attente en arrière-plan, sans jamais bloquer la file d'attente principale.
Il en découle quelques principes. Le premier écran s'appuie sur les données déjà présentes sur l'appareil ; ainsi, l'application affiche immédiatement des informations réelles et se met à jour en arrière-plan si nécessaire. Les fonctionnalités qui ne sont pas nécessaires sur le premier écran ne sont activées que lorsque l'utilisateur en fait la demande. Et chaque fois que nous sommes tentés d’ajouter une bibliothèque, nous nous demandons d’abord ce qu’elle fait au lancement avant de nous demander ce qu’elle peut nous apporter.
Les compromis
Cette rigueur a un coût. Renoncer à un SDK pratique implique parfois d’écrire et de maintenir soi-même le code équivalent. Afficher en priorité les données locales signifie concevoir l’application en tenant compte du fait qu’elles puissent être légèrement obsolètes. Le chargement différé nécessite une attention particulière pour éviter tout ralentissement lors de la première ouverture d’un écran plus lourd. Nous acceptons ces coûts car l’alternative serait une petite perte de performance à chaque lancement, pour toujours, pour tout le monde.
Nos erreurs
Le temps de lancement ne se détériore que rarement d’un seul coup. Il s’érode progressivement : un peu de code de configuration par-ci, une vérification supplémentaire par-là, chacun inoffensif en soi. Nous l’avons appris à nos dépens, en remarquant trop tard qu’une application mettait désormais plus de temps à s’ouvrir, sans qu’aucun commit en particulier ne soit en cause. Désormais, le temps de lancement est vérifié sur l’appareil de référence à chaque version, ce qui permet de détecter les dérives dès qu’elles sont encore minimes.
Ce principe s'applique également à nos autres plateformes. Une application Windows ou une fenêtre contextuelle d'extension de navigateur dispose de sa propre version du « démarrage à froid », et la même règle s'applique : afficher immédiatement quelque chose d'utile, et remettre tout le reste à plus tard.
Pourquoi cela en vaut la peine
La rigueur est rentable. Une fois que le lancement est rapide, tout le reste l'est aussi — car les mêmes règles s'appliquent partout.