Comment améliorer les performances de votre application de style Metro

Blog des développeurs d'applications Windows 8

Indications sur la conception d'applications de style Metro pour Windows 8, par l'équipe d'ingénierie de Windows 8

Comment améliorer les performances de votre application de style Metro

  • Comments 0

Tout le monde déteste les applications lentes ou peu réactives. Les utilisateurs souhaitent profiter d'applications qui répondent immédiatement aux interactions tactiles, aux appuis, aux clics, aux mouvements et aux touches. Ils veulent que les animations soient fluides et souhaitent pouvoir lire leur musique et leurs vidéos, les mettre en pause et reprendre leur lecture rapidement, sans jamais devoir patienter pendant la réactivation de l'application. Voici le premier billet d'une série destinée à expliquer comment rendre vos applications rapides et fluides.

Nos équipes de développement ont beaucoup réfléchi aux différentes possibilités d'optimisation des performances des applications de style Metro. C'est ainsi que nous avons réussi à déterminer comment optimiser la plateforme pour atteindre nos objectifs en matière de rapidité et de fluidité. Nous avons aussi pu identifier les choses à faire et à ne pas faire pour améliorer l'expérience utilisateur de vos applications. À travers ce blog, je vais partager avec vous quelques-unes des conclusions tirées de notre propre expérience, pour vous aider à proposer à vos clients la meilleure expérience utilisateur possible.

Performances et psychologie

Les performances ne sont pas qu'un problème de chronomètre et d'efficacité des algorithmes. En matière de performances, je préfère souvent opter pour une approche globale et étudier comment les utilisateurs exploitent leurs applications. Fondamentalement, qu'est-ce qu'une application rapide et fluide ? Pour répondre à cette question, nous pouvons séparer les expériences de l'utilisateur en trois catégories : perception, tolérance et réactivité.

Perception : tout est toujours trop long !

La perception participe à l'impression de rapidité d'une application. La perception des performances par l'utilisateur se définit comme suit : dans quelle mesure l'utilisateur a-t-il trouvé qu'il pouvait réaliser les tâches souhaitées rapidement dans l'application ? Dans un monde parfait, la perception de l'utilisateur correspondrait à la réalité. Malheureusement, cela est rarement le cas et par conséquent, le temps perçu a plus d'importance que le temps réel. Vous est-il déjà arrivé de laisser un processus d'installation se terminer de lui-même, pour réaliser quelques minutes plus tard qu'il s'était interrompu parce vous n'aviez pas répondu à la question affichée dans une boîte de dialogue ?

En fait, plus le nombre d'étapes que vous vous souvenez avoir réalisées dans le cadre d'un processus est élevé, plus ce processus semble lent.

À faire :
  • Réduire le délai entre les activités devant être réalisées par l'utilisateur pour accomplir la tâche souhaitée.
  • Si l'utilisateur doit répondre à des questions ou saisir des informations, poser toutes les questions dès le départ.
À ne pas faire :
  • Séparer les activités de l'utilisateur en plusieurs phases séparées par un délai.

Tolérance : le temps passe plus vite lorsque vous vous amusez

La tolérance participe à l'impression de rapidité et de fluidité d'une application. Si la perception correspond à la capacité du client à se rappeler du temps passé à accomplir telle ou telle tâche, la tolérance correspond quant à elle à la façon dont l'utilisateur juge ce temps passé.

Lorsqu'un utilisateur ne sait pas combien de temps va prendre une opération, l'attente est toujours pénible. Supposons que vous utilisiez une application permettant d'éditer des photos. Lorsque vous cliquez pour appliquer un filtre, l'application ne répond plus pendant quelques instants. Ce temps de blocage devient vite intolérable, même s'il ne dure quelques secondes.

Les applications de photo ont résolu ce problème en ajoutant une barre de progression ou une petite animation pour indiquer que le filtre est en cours d'application. L'utilisateur est alors prêt à attendre beaucoup plus longtemps, car il est certain que l'application n'est pas totalement bloquée. L'application est ainsi rapide et fluide, et la différence est fondamentale.

À faire :

  • Prendre le temps d'identifier les parties de votre application qui sont susceptibles de nécessiter un temps de chargement relativement important (plus d'une seconde).
  • Prendre les mesures nécessaires pour limiter, voire lever les doutes de l'utilisateur quant à un éventuel blocage, dans ces scénarios d'utilisation.
  • Indiquer visuellement à l'utilisateur la progression du processus et la durée restante requise pour accomplir l'opération.
  • Utiliser des API asynchrones pour empêcher le blocage du thread d'interface utilisateur et éviter de donner l'impression que l'application est gelée.

À ne pas faire :

  • Entreprendre des actions longues sans informer l'utilisateur.

Réactivité : réflexes < réactions < accusé de réception

La réactivité participe à l'impression de fluidité d'une application. Si la tolérance mesure l'optimisme et l'indulgence de l'utilisateur vis-à-vis du temps écoulé, le concept de réactivité part du principe que l'optimisme vis-à-vis du temps écoulé dépend de l'opération réalisée. Pour mesurer et évaluer les performances d'une opération, il est nécessaire de la comparer à un intervalle de temps. J'appelle ces intervalles des classes d'interaction. En interne, nous utilisons ces classes d'interaction pour définir les objectifs de certains scénarios clés en termes de réactivité dans l'ensemble de Windows, et pour définir comme bogue tout échec dans l'atteinte de ces objectifs.

Classe d'interaction

Cible

Limite supérieure

Perception humaine

Scénario type

Instantanée

<= 50 ms

100 ms

Aucun délai perceptible.

Réponse à une entrée : clic de souris, appui sur un bouton, etc.

Rapide

50 à 100 ms

200 ms

Délai très peu perceptible. Aucun retour requis.

Panoramique/Défilement.

Standard

100 à 300 ms

500 ms

Opération courte, mais trop lente pour être considérée comme rapide. Aucun retour requis.

Ouverture d'une boîte de dialogue au sein d'une page (info-bulle, fenêtre contextuelle, menu volant, toast, etc.).

Réactive

300 à 500 ms

1 s

L'opération n'est pas rapide, mais donne quand même une impression de réactivité. Aucun retour requis.

Accès à une nouvelle page, zoom, affichage de données traitées ou prêtes.

Continue

>500 ms

10 s

Attente moyenne, l'impression de réactivité a disparu. L'opération n'est pas suffisamment longue pour entreprendre une autre action. Un retour peut être requis.

Lancement ou ancrage d'une application, messages d'erreur, délais d'expiration, indicateurs de progression des mises à jour.

Étendue

>5 s

>1 minute

L'opération est suffisamment longue pour entreprendre une autre action pendant le délai d'attente. Un retour peut être requis.

Synchronisation ou indexation d'un appareil ou d'une bibliothèque.

À faire :

  • Associer les scénarios importants de votre application à une classe d'interaction représentant l'expérience utilisateur souhaitée.
  • Identifier les scénarios qui n'atteignent pas ces objectifs et les optimiser.
  • Identifier les scénarios pouvant nécessiter un retour et fournir ce retour à l'utilisateur.

Principales expériences à optimiser

Les problèmes de performances peuvent prendre des formes bien différentes. Ils peuvent réduire l'autonomie de la batterie, retarder les mouvements de panoramique et de défilement par rapport aux interactions tactiles, ou même donner l'impression qu'une application est gelée pendant une longue période. Je sais bien que vous n'avez pas un temps illimité à consacrer à l'amélioration des performances. Aussi, cette section passe en revue certaines astuces permettant d'identifier les zones où l'optimisation aura le plus d'impact, ainsi que certaines conseils facilitant la mise en œuvre de ces optimisations.

En matière d'optimisation, sachez que pour que l'utilisateur perçoive une différence, le processus doit être 20 % plus rapide ou 20 % plus lent.

Schéma montrant qu'une différence de durée de 20 % dans un sens ou dans l'autre est perceptible.

Vous trouverez peut-être dans votre application certaines optimisations très simples à mettre en œuvre pour améliorer sensiblement plusieurs scénarios clés. Une fois ces problèmes corrigés, vous aurez encore moins de chances de rencontrer un problème de performances unique pouvant réduire immédiatement la durée d'un processus de 20 %. Bien souvent, les problèmes d'expérience utilisateur sont dus à une accumulation de petits problèmes liés les uns aux autres. Dans les paragraphes ci-dessous, je vais vous présenter un outil idéal pour identifier ces petits problèmes.

Profilage des applications

L'une des techniques les plus simples et les plus faciles à mettre en œuvre pour déterminer où les optimisations peuvent avoir le plus de conséquences consiste à réaliser un profilage de votre application. Le profilage fournit des données sur le temps passé par votre application à accomplir différentes fonctions. Vous pouvez ainsi identifier les principales opérations réalisées par l'application. Un outil performant de profilage est justement disponible dans Visual Studio 11. Vous pouvez y accéder dans Windows 8 Consumer Preview.

Avant d'aller plus loin, rappelons que Windows 8 sera exécuté sur un large éventail d'appareils. Aussi, si vous mesurez les performances sur un ordinateur très puissant, vous ne disposerez sans doute pas d'informations fiables sur les performances de votre application sur d'autres types d'appareils. Dans mon cas, j'utilise la plupart du temps un ordinateur portable d'entrée de gamme pour mesurer les performances. Pour plus d'informations à ce sujet, consultez le blog intitulé Exécution de la version Consumer Preview : recommandations système.

Voici comment préparer un ordinateur en vue de mesurer les performances d'une application :

  1. Vérifiez que l'ordinateur est branché et qu'il ne fonctionne pas sur batterie : pour économiser de l'énergie, de nombreux systèmes fonctionnent de façon différente sur batterie.
  2. N'utilisez pas le Bureau à distance pour effectuer des mesures, car il est susceptible de désactiver l'accélération matérielle et d'altérer les résultats.
  3. Vérifiez que la mémoire totale du système n'est pas utilisée à plus de 50 %. Si c'est le cas, fermez les applications jusqu'à atteindre 50 %, de façon à mesurer l'incidence réelle de votre application et non celle des autres processus.

Pour commencer à profiler votre application, procédez comme suit :

  1. Lancez votre application dans Visual Studio.
  2. Dans le menu Déboguer, sélectionnez l'une des deux options d'analyse des performances :
  3. Menu contenant les options Démarrer l'analyse des performances (Alt+F2), Démarrer l'analyse des performances en pause (Ctrl+Alt+F2).

    • Start Performance Analysis (Démarrer l'analyse des performances) : commencez immédiatement à enregistrer les informations relatives à l'utilisation et lancez l'application.
    • Start Performance Analysis Paused (Démarrer l'analyse des performances en mode pause) : lancez l'application pour activer ensuite l'enregistrement des informations. Cette option permet d'accéder à l'application dans un état spécifique avant d'enregistrer les informations (par exemple pour tester un scénario d'utilisation spécifique).
  4. Une fois que vous avez réalisé les actions à mesurer, retournez dans Visual Studio et cliquez sur Arrêtez le profilage. VS génère alors un rapport et affiche les principales informations relatives aux activités de l'application.

Lien Arrêtez le profilage dans Visual Studio.

Les vues Arborescence des appels et Informations relatives à la fonction font partie des vues les plus utiles du rapport de performances. Dans la première de ces vues, vous pouvez voir toutes les fonctions appelées par votre application au cours de son exécution, le nombre d'appels et la durée d'exécution. Vous disposez également d'un bouton Développer le chemin réactif, qui indique quelles fonctions ont mis le plus de temps à s'exécuter. Pour mettre en œuvre vos optimisations, nous vous conseillons de commencer par consulter ces informations, car elles ont des chances d'avoir un effet bénéfique important.

Bouton Développer le chemin réactif dans la vue Arborescence des appels.

Le rapport indique les temps inclusifs et exclusifs de chaque fonction. Le temps exclusif mesure le pourcentage de temps passé à exécuter du code au sein de cette fonction. Le temps inclusif correspond au pourcentage de temps écoulé entre l'appel de la fonction et son renvoi. En d'autres termes, il ne s'agit pas uniquement du temps passé à exécuter du code dans la fonction, mais aussi du temps passé à exécuter du code dans n'importe quelle fonction appelée.

Pour toutes les fonctions de votre application, vous pouvez ouvrir la vue Informations relatives à la fonction pour obtenir des informations détaillées sur les opérations réalisées par la fonction, notamment le code exécuté, les fonctions appelées et le temps d'exécution de ces fonctions. Dans l'exemple indiqué sur la figure, la fonction Array.concat est le principal contributeur du chemin réactif et accapare 29,7 % du temps d'exécution de l'application. La vue Informations relatives à la fonction montre que la fonction Array.concat ne prend qu'environ 12,6 % du temps (en orange) et que la majorité du temps est en fait passée dans la fonction get_MainResourceMap, que la fonction de concaténation appelle dans le cadre de son exécution (en violet). Vous pouvez ensuite cliquer sur chacune de ces fonctions pour accéder à des détails supplémentaires.

La vue Informations relatives à la fonction concernant Array.concat indique le pourcentage de fonctions d'appel, le pourcentage de fonctions actuelles et le pourcentage de fonctions appelées.

Quelques semaines avant la publication de Windows 8 Consumer Preview, alors que j'utilisais une application, j'ai remarqué que mon ordinateur portable montait en température et que ses ventilateurs se mettaient à tourner. En collaborant avec l'éditeur de l'application, nous avons utilisé le profilage pour identifier les chemins de code entraînant une utilisation excessive et inutile des ressources processeur, et corriger le problème. J'ai pu constater immédiatement la différence et d'autres scénarios de l'application (l'ancrage, par exemple) ont également été optimisés suite à ces modifications.

Votre meilleur allié : la suspension

Le lancement d'une application a lieu lorsque l'application n'est pas suspendue : si elle est suspendue, elle est réaffichée presque instantanément, dès sa reprise. Grâce à la suspension de votre application, vous pouvez gérer la perception, la tolérance et la réactivité. Les utilisateurs profitent plus rapidement de votre application et n'ont pas à attendre que votre application se charge à chaque fois qu'ils l'utilisent. Pour faire simple, le fait d'empêcher l'arrêt de votre application offre des avantages significatifs en termes de performances. Pour cela, le moyen le plus simple consiste à conserver un niveau d'utilisation de mémoire faible lorsque l'application est suspendue.

Avant d'être suspendue, votre application dispose de quelques secondes pour réaliser différentes opérations. Profitez-en pour décharger les objets volumineux qui peuvent être facilement récupérés lors de la reprise. L'encombrement mémoire de votre application reste ainsi relativement faible et vous réduisez les risques que le système arrête votre application pour laisser la place à d'autres processus. Voici comment vérifier que votre application est correctement suspendue :

  1. Lancez l'application, puis accédez à nouveau au Bureau.
  2. Lancez le Gestionnaire des tâches en appuyant sur Ctrl+Maj+Échap, puis cliquez sur « Plus de détails » pour afficher toutes les options disponibles.
  3. Cliquez sur Affichage > Valeurs d'état > Afficher l'état Suspendu.

Dans le menu Affichage, l'option Regrouper par type est sélectionnée, tout comme l'option Afficher l'état Suspendu située plus bas.

Au bout de quelques secondes, la mention « Suspendu » apparaît près du nom de votre application. Pendant qu'elle est suspendue, vérifiez que la mémoire utilisée par la plage de travail privée de l'application est inférieure à celle utilisée lorsque l'application est en cours d'exécution. Je vous recommande de cibler les valeurs de mémoire suivante lorsque votre application est suspendue, selon sa complexité et sa taille globale :

Complexité approximative de l'application

Mémoire maximale utilisée par la plage de travail privée lorsque l'application est suspendue

Application minimale (par exemple, Hello World)

40 à 60 Mo

Application moyenne (par exemple Weather)

60 à 80 Mo

Grosse application (par exemple Windows Live Photos)

120 à 150 Mo

Voici comment connaître la quantité de mémoire utilisée par votre application lorsqu'elle est suspendue :

  1. Vérifiez que l'application est suspendue, en suivant la procédure ci-dessus.
  2. Cliquez avec le bouton droit de la souris sur le nom de l'application dans le Gestionnaire des tâches, puis cliquez sur « Accéder aux détails ». Vous découvrez ainsi des détails supplémentaires sur le processus de votre application (WWAHost.exe est le processus de toutes les applications de style Metro utilisant Javascript ; dans le cas contraire, le nom du processus correspond au nom de l'application).
  3. Vérifiez que la colonne « Mémoire (plage de travail privée) » est affichée. Si cela n'est pas le cas, cliquez avec le bouton droit de la souris sur une colonne, cliquez sur Sélectionner des colonnes, puis sélectionnez Mémoire (plage de travail privée).
  4. La colonne Mémoire (plage de travail privée) est sélectionnée dans la liste des noms de colonne.

  5. La valeur figurant dans cette colonne correspond à la plage de travail privée de votre application.


20 736 Ko de mémoire sont utilisés.

Se comporter en bon citoyen au sein de l'écosystème d'applications

Vous serez peut-être déçu de l'apprendre, mais vos clients utilisent d'autres applications que les vôtres :-). Par conséquent, comportez-vous en bon citoyen lorsque vous exécutez vos applications sur le système de l'utilisateur, de sorte qu'il ne soit pas tenté d'attribuer les latences perçues dans le système à votre application et qu'il ne les associe pas mentalement à de mauvaises performances ou à une mauvaise autonomie du système. Voici quelques conseils pour vous aider à faire cohabiter facilement votre application avec d'autres applications.

N'utilisez pas exagérément les ressources mémoire

Le travail du système consiste à adapter les besoins en ressources de toutes les applications de style Metro, en arrêtant automatiquement les applications suspendues afin de laisser la place à de nouvelles applications et de permettre à l'utilisateur de ne pas avoir à gérer lui-même les ressources. Ce principe présente un effet secondaire : si une application demande une grande quantité de mémoire, les autres applications risquent d'être arrêtées, même si l'application libère la mémoire peu de temps après l'avoir demandée. Pour éviter de rencontrer ce problème lors du traitement d'opérations complexes, la meilleure approche consiste à les traiter sous forme de petits blocs.

Si vous développez dans un langage à gestion de mémoire (par exemple JavaScript ou C#), il est extrêmement difficile de contrôler à quel moment les allocations de mémoire ont lieu. Cependant, ne tombez pas dans le piège consistant à charger des ressources trop grandes pour la résolution du système actuel, pour les mettre ensuite à l'échelle. Vous pouvez utiliser les nouvelles API de miniatures pour acquérir les ressources adaptées à la résolution cible et éviter de trop consommer les ressources. Nous avons utilisé cette approche pour réduire de façon significative l'utilisation de la mémoire d'un jeu de puzzle utilisé lors des tests.

Quel que soit le langage de programmation, je vous recommande de cibler les valeurs de mémoire d'exécution suivantes, selon la complexité et la taille globale de votre application :

Complexité approximative de l'application

Plage de travail maximale totale

Application minimale (par exemple, Hello World)

50 à 70 Mo

Application moyenne (par exemple Weather)

80 à 100 Mo

Grosse application (par exemple Photos)

120 à 150 Mo

Voici comment connaître la quantité de mémoire utilisée par votre application lorsqu'elle est en cours d'exécution :

  1. Lancez le Gestionnaire des tâches en appuyant sur Ctrl+Maj+Échap, puis cliquez sur Plus de détails pour afficher toutes les options disponibles.
  2. Cliquez sur l'élément de menu Options, puis vérifiez que l'option Toujours visible est sélectionnée.
  3. Lancez votre application. Lorsque l'application apparaît dans le Gestionnaire des tâches, cliquez dessus avec le bouton droit de la souris, puis cliquez sur Accéder aux détails.
  4. Vérifiez que la colonne Plage de travail (mémoire) est affichée. Si cela n'est pas le cas, cliquez avec le bouton droit de la souris sur une colonne, puis cliquez sur Sélectionner des colonnes. Cochez la case Plage de travail (mémoire).

    La colonne Plage de travail (mémoire) est sélectionnée dans la liste des colonnes.

  5. La valeur figurant dans cette colonne correspond à la plage de travail totale de votre application.

Limitez l'utilisation des ressources système lorsque l'application est inactive ou ancrée

L'autonomie de l'appareil fait partie des principales préoccupations des utilisateurs. Par conséquent, je vous recommande de faire en sorte que vos applications de style Metro participent aux économies d'énergie en se déchargeant des ressources système lorsque l'utilisateur n'interagit pas directement avec elles. Voici quelques conseils permettant de réduire l'utilisation des ressources :

Ne lisez pas d'animations, de musique ou de vidéos en arrière-plan lorsque l'application est ancrée.

  • Votre application n'est plus au centre de l'attention. Faites en sorte qu'elle soit esthétiquement réussie et utilisable, mais n'accaparez pas les ressources mises à la disposition de l'application principale et n'utilisez pas la batterie.
  • Nous supposons évidemment que votre application n'est pas un client de lecture de musique ou de vidéos.

Ne lisez pas d'animations, de musique ou de vidéos en arrière-plan sous forme de boucle infinie.

  • Si l'utilisateur n'a pas interagi avec l'application au bout d'un court délai, mettez en pause ces activités. Vous pourrez les reprendre en toute sécurité la prochaine fois que l'utilisateur interagira avec votre application.
  • J'ai constaté que l'utilisation processeur de certaines applications passait de 40 % à 0 % en période d'inactivité, grâce à la simple mise en pause des activités d'arrière-plan.

Ne procédez pas à des opérations de mise en cache de fichiers, de synchronisation d'appareils, ni à d'autres opérations sollicitant beaucoup les disques lorsque l'application est ancrée ou inactive.

  • L'utilisation du disque augmente de façon inutile les temps de recherche des autres opérations et consomme beaucoup d'énergie.

Pour aller plus loin...

Dans ce billet, j'ai expliqué sous quel angle examiner les performances, indiqué plusieurs méthodes permettant de définir des objectifs pour les expériences clés de votre application et évoqué certains outils permettant d'identifier les points susceptibles de nécessiter une optimisation. Dans mon prochain billet, j'expliquerai comment mettre en œuvre ces optimisations pour résoudre les problèmes majeurs et comment éviter certains pièges courants. J'espère que ces quelques conseils vous seront utiles !

À très bientôt !

-- David Tepper, chef de projet, Windows

  • Loading...
Leave a Comment
  • Please add 4 and 3 and type the answer here:
  • Post