reformulation des pratiques 006 a 010

dev
DEMEY Fanny 2024-02-02 16:13:15 +01:00
parent 9c8294b0ac
commit b3864b8413
14 changed files with 899 additions and 1 deletions

2
.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
/.idea/
/.idea/*

153
CONTRIBUTING.md Normal file
View File

@ -0,0 +1,153 @@
# Contribuer au référentiel de bonnes pratiques
Tout personne qui le souhaite peut se proposer pour contribuer au référentiel.
Les règles du présent document devront être respectées.
L'équipe projet en charge de ce repository s'assure de la bonne tenue de ces règles.
## But des contributions
Les contributions ont pour but :
- De supprimer les bonnes pratiques obsolètes, non applicables ou sans effet
- Dajouter des bonnes pratiques qui semblent pertinentes, sont issues du terrain
- Dassocier aux nouvelles bonnes pratiques une règle de conformité
- De vérifier, améliorer le cas échéant les bonnes pratiques existantes ainsi que leur règle de conformité
- De proposer toute idée qui pourrait améliorer le référentiel d'une manière générale et le cas échéant la mettre en place
## Règles générales
- Tout le monde a sa place, chacun peut apporter son expérience
- La convivialité, le partage, la courtoisie et la bienveillance sont des règles d'or dans les échanges
- Chaque bonne pratique doit être le résultat d'un retour terrain ou d'une approche scientifique
- Ces bonnes pratiques sont aussi un aide mémoire donc même une bonne pratique simple, de bon sens peut avoir sa place
## Equipe Projet
L'équipe projet est constituée de:
-
- [Fanny Demey](https://github.com/FannyDemey)
- [Emmanuel Demey](https://github.com/EmmanuelDemey)
- [Thomas Lemaire](https://github.com/ACTLEM)
Cette équipe s'assure que les règles instaurées pour la contribution soient respectées.
En cas de désaccord entre contributeurs, son rôle est aussi de trancher une décision.
L'équipe projet fait preuve de transparence et fait en sorte que les décisions soient les plus collégiales possibles.
L'équipe projet est responsable de la validation définitive des `Pull Request` et donc de l'intégration de la proposition d'ajout, de modification ou de suppression dans le référentiel.
Un membre de l'équipe projet peut soumettre une proposition aux contributeurs mais ne peut pas être responsable seul de la validation ou non de celle-ci : il faut un consensus de l'équipe projet.
## Proposition
Chaque proposition d'ajout, de modification majeure ou de suppression de bonnes pratiques doit passer par [une discussion](https://github.com/cnumr/best-practices/discussions/categories/bonnes-pratiques).
Le titre de la discussion doit être explicite et doit spécifier s'il s'agit d'un ajout, d'une modification majeure ou d'une suppression.
Une modification majeure peut être:
- Une modification importante du niveau de priorité, c'est à dire des niveaux de mise en oeuvre et d'impacts écologique
- L'ajout ou la suppression d'élément dans la définition de la règle
- L'ajout ou la suppression d'exemples
- La modification de la règle de conformité
Tout contributeur peut donner son avis sur la proposition:
- En cas d'accord, un contributeur clique sur la "flèche vers le haut"
- En cas de désaccord, un contributeur ajoute un "pouce bas" et devra obligatoirement expliquer via un commentaire les raisons de son désaccord
- En cas d'incompréhension, il peut entamer une discussion pour demander des précisions
- En cas d'idée d'amélioration, il peut la proposer
Lorsqu'une proposition reçoit plusieurs votes positifs, l'équipe projet est sollicitée et évalue la pertinence de la bonne pratique.
Les cas suivants peuvent se produire:
- La proposition est validée et le contributeur peut créer une `Issue` avec la discussion en référence
- La proposition est définitivement rejetée avec justification
- La proposition doit être retravaillée avant une décision finale
L'`Issue` créée devra contenir le tag `création`, `modification` ou `suppression` suivant le type de proposition et être rattachée au projet [`Bonnes Pratiques V5`](https://github.com/cnumr/best-practices/projects/2).
En cas d'ajout, le fichier sera nommé suivant le pattern suivant: `BP-5xxx-fr.md` avec `5xxx` le numéro de la bonne pratique qui sera défini par l'équipe projet.
Le fichier sera à copier à partir du [template](./resources/BP_xxxx_fr.md)
Une `Pull Request` associée à l'`Issue` sera créée et soumise à l'équipe projet qui est en charge de la revue.
La création de `Pull Request` suite le processus classique au sein de Github, à savoir:
- Création d'un `fork` personnelle de la personne en charge de la `Pull Request`
- Ajout du repository d'origine comme remote (`upstream`)
- Création d'une branche sur le fork personnel
- Créer une `Pull Request` à partir du fork en mettant comme cible la branche `main` du repository cible
## Amélioration
Pour les améliorations comme:
- Une correction d'orthographe, de grammaire ou de conjugaison
- Une autre formulation
- Une autre mise en forme
Il n'est pas nécessaire de passer par une discussion, il faut:
- Créer une `Issue` avec un intitulé explicite et les tags `modification` et `mineur`
- Développer et créer la PR associée sans oublier la référence à l'`Issue`
## Contenu d'une bonne pratique
Chaque bonne pratique devra obligatoirement contenir:
- Un titre
- Un degré de priorité (sur 5, 5 = prioritaire, 1 = non prioritaire)
- Une difficulté de mise en oeuvre (sur 5, 5 = facile, 1 = difficile)
- Un niveau d'impact écologique (sur 5, 5 = fort, 1 = faible)
- Une description
- Une règle de validation et un seuil de conformité
Les éléments suivants sont facultatifs:
- Un ou des exemples
- Une solution alternative
### Règle de validation et seuil de conformité
La règle de validation permet de tester la mise en oeuvre de la bonne pratique avec une approche objective.
Le seuil de conformité associe à la règle de validation une valeur numérique (seuil) qui permet de décider de façon binaire (oui/non) si la bonne pratique a été mise en oeuvre ou pas.
L'ensemble des règles de validation et des seuils de conformité permettent d'établir un niveau de maturité atteint par le service numérique.
### Définition des niveaux
Trois niveaux doivent être définis pour une bonne pratique :
1. Mise en oeuvre (facilité ou difficulté à mettre en oeuvre la bonne pratique)
2. Impacts environnemental (contribution plus ou moins forte à la réduction des impacts env.)
3. Priorité (ce niveau est défini en fonction de 1. et 2.)
Chacun de ces niveaux est défini par une note de 1 à 5.
#### Mise en oeuvre (higher is better)
La facilité ou difficulté de mise en oeuvre peut être évaluée de la manière suivante :
1. La mise en oeuvre nécessite un haut niveau d'expertise ET une refonte en profondeur du projet
2. La mise en oeuvre nécessite un haut niveau d'expertise OU une refonte en profondeur du projet
3. Le mise en oeuvre demande une compétence particulière sans être rare (ex: SEO, DBA, ...) ET n'a pas besoin de refonte en profondeur du projet
4. La mise en oeuvre ne nécessite pas compétence particulière OU n'a pas d'effet de bord sur le reste du projet
5. La mise en oeuvre ne nécessite pas compétence particulière ET n'a pas d'effet de bord sur le reste du projet
#### Impact environnemental (higher is better)
Cet apport peut être évalué de la manière suivante :
1. Elle réduit la consommation électrique des réseaux ou serveurs à équipements constants
2. Elle réduit la consommation électrique sur la majorité des terminaux utilisateurs
3. Elle limite le besoin en ressources informatiques côté serveur
4. Elle limite le risque de saturation des réseaux mobiles ou fixes
5. Elle limite les risques d'obsolescence des terminaux utilisateurs
#### Priorité (higher is better)
Le niveau de priorité est proposé librement par le contributeur et s'appuie sur la Mise en oeuvre et l'Impact environnemental.

155
README.md
View File

@ -1 +1,154 @@
# mobile-best-practice
# Bonne pratiques d'écoconception appliqué au mobile
## Contexte
L'objectif de ce document est de fournir un référentiel d'écoconception adapté au mobile. L'application des bonnes pratiques ci-dessous ont toutes un but commun : prolonger la durée de vie des terminaux des utilisateurs et utilisatrices.
## Les besoins
Étant donné les évolutions continues du mobile, ce référentiel a besoin de régulièrement être mis à jour.
Toute proposition ou idée d'amélioration, de modification ou de suppression est bienvenue.
## Comment contribuer ?
N'hésitez pas à lire [le guide des contributeurs](CONTRIBUTING.md).
## La liste des Bonnes Pratiques
Produit :
* [Éliminer les fonctionnalités non essentielles](chapters/MBP_001_fr.md)
* [Quantifier précisément le besoin](chapters/MBP_002_fr.md)
UI/UX :
* [Optimiser le parcours utilisateur](chapters/MBP_003_fr.md)
* [Préférer la saisie assistée à l'autocomplétion](chapters/MBP_004_fr.md)
* [Favoriser un design simple, épuré, adapté au mobile](/chapters/MBP_005_fr.md)
* [Optimiser la récupération en fonction du cycle de vie de l'application](chapters/MBP_006_fr.md)
* [Libérer la mémoire des traitements consommateurs en fonction de l'état de l'application](chapters/MBP_006bis_fr.md)
*
* [Stocker localement les données de configuration non liées aux données du serveur](chapters/MBP_007_fr.md) // TODO à discuter car côté mobile, beaucoup des données statiques sont déjà sur l'appareil.
* [Déployer un Android App Bundle (AAB) plutôt qu'un APK](chapters/MBP_008_fr.md)
* [Supprimer les ressources non utilisées](chapters/MBP_009_fr.md)
* [Minifier et obfusquer le code](chapters/MBP_010_fr.md)
// TODO SavedStateHandle
// Repository (stratégie offline)
// TODO pas encore fait la suite
* [Proposer un traitement asynchrone lorsque c'est possible](/chapters/BP_008_fr.md) // TODO à voir si équivalent.
* [Choisir les technologies les plus adaptées](/chapters/BP_015_fr.md)
* [Utiliser certains forks applicatifs orientés "performance"](/chapters/BP_016_fr.md)
* [Choisir un format de données adapté](/chapters/BP_017_fr.md)
* [Limiter le nombre de domaine servant les ressources](/chapters/BP_018_fr.md)
* [Remplacer les boutons officiels de partage des réseaux sociaux](/chapters/BP_019_fr.md)
* [Découper les CSS](/chapters/BP_021_fr.md)
* [Limiter le nombre de CSS](/chapters/BP_022_fr.md)
* [Préférer les CSS aux images](/chapters/BP_023_fr.md)
* [Écrire des sélecteurs CSS efficaces](/chapters/BP_024_fr.md)
* [Grouper les déclarations CSS similaires](/chapters/BP_025_fr.md)
* [Utiliser les notations CSS abrégées](/chapters/BP_026_fr.md)
* [Fournir une CSS print](/chapters/BP_027_fr.md)
* [Favoriser les polices standards](/chapters/BP_029_fr.md)
* [Préférer les glyphs aux images](/chapters/BP_030_fr.md)
* [Valider les pages auprès du W3C](/chapters/BP_031_fr.md)
* [Externaliser les CSS et JavaScript](/chapters/BP_032_fr.md)
* [Ne pas redimensionner les images coté navigateur](/chapters/BP_034_fr.md)
* [Éviter d'utiliser des images matricielles pour l'interface](/chapters/BP_035_fr.md)
* [Optimiser les images vectorielles](/chapters/BP_036_fr.md)
* [Utiliser le chargement paresseux](/chapters/BP_037_fr.md)
* [Utiliser le rechargement partiel d'une zone de contenu](/chapters/BP_038_fr.md)
* [Éviter les animations JavaScript / CSS](/chapters/BP_039_fr.md)
* [N'utilisez que les portions indispensables des librairies JavaScript et frameworks CSS](/chapters/BP_040_fr.md)
* [Ne pas faire de modification du DOM lorsquon le traverse](/chapters/BP_041_fr.md)
* [Rendre les éléments du DOM invisibles lors de leur modification](/chapters/BP_042_fr.md)
* [Réduire au maximum le repaint (appearence) et le reflow (layout)](/chapters/BP_043_fr.md)
* [Utiliser la délégation d'évènements](/chapters/BP_044_fr.md)
* [Modifier plusieurs propriétés CSS en 1 seule fois](/chapters/BP_045_fr.md)
* [Valider votre code avec un Linter](/chapters/BP_046_fr.md)
* [Mettre en cache les objets souvent accédés en JavaScript](/chapters/BP_049_fr.md)
* [Réduire les accès au DOM via JavaScript](/chapters/BP_054_fr.md)
* [Utiliser tous les niveaux de cache du CMS](/chapters/BP_057_fr.md)
* [Optimiser et générer les médias avant importation sur un CMS](/chapters/BP_058_fr.md)
* [Encoder les sons en dehors du CMS](/chapters/BP_060_fr.md)
* [Mettre en cache les données calculées souvent utilisées](/chapters/BP_064_fr.md)
* [Supprimer tous les warning et toutes les notices](/chapters/BP_070_fr.md)
* [Éviter d'effectuer des requêtes SQL à lintérieur dune boucle](/chapters/BP_072_fr.md)
* [Ne se connecter à une base de données que si nécessaire](/chapters/BP_073_fr.md)
* [Optimiser les requêtes aux bases de données](/chapters/BP_075_fr.md)
* [Éviter le transfert d'une grande quantité de données pour réaliser un traitement](/chapters/BP_076_fr.md)
* [Minifier les fichiers CSS, JavaScript, HTML et SVG](/chapters/BP_077_fr.md)
* [Compresser les fichiers CSS, JavaScript, HTML et SVG](/chapters/BP_078_fr.md)
* [Combiner les fichiers CSS et JavaScript](/chapters/BP_079_fr.md)
* [Optimiser les images](/chapters/BP_080_fr.md)
* [Optimiser la taille des cookies](/chapters/BP_082_fr.md)
* [Favoriser HSTS Preload list aux redirections 301](/chapters/BP_084_fr.md)
* [Mettre en place un plan de fin de vie du site](/chapters/BP_085_fr.md)
* [Choisir un hébergeur "éco-responsable"](/chapters/BP_086_fr.md)
* [Privilégier un fournisseur d'électricité écoresponsable](/chapters/BP_087_fr.md)
* [Adapter la qualité de service et le niveau de disponibilité](/chapters/BP_088_fr.md)
* [Utiliser des serveurs virtualisés](/chapters/BP_089_fr.md)
* [Optimiser l'efficacité énergétique des serveurs](/chapters/BP_090_fr.md)
* [Installer le minimum requis sur le serveur](/chapters/BP_091_fr.md)
* [Mettre les caches entièrement en RAM (opcode et kvs)](/chapters/BP_092_fr.md)
* [Stocker les données dans le cloud](/chapters/BP_093_fr.md)
* [Héberger les ressources (CSS/JS) sur un domaine sans cookie](/chapters/BP_094_fr.md)
* [Éviter les redirections](/chapters/BP_095_fr.md)
* [Afficher des pages d'erreur statiques](/chapters/BP_096_fr.md)
* [Utiliser un serveur asynchrone](/chapters/BP_097_fr.md)
* [Utiliser un CDN](/chapters/BP_098_fr.md)
* [Utiliser un cache HTTP](/chapters/BP_099_fr.md)
* [Ajouter des entêtes Expires ou Cache-Control](/chapters/BP_101_fr.md)
* [Mettre en cache les réponses Ajax](/chapters/BP_102_fr.md)
* [Réduire au nécessaire les logs des serveurs](/chapters/BP_103_fr.md)
* [Désactiver le DNS lookup dApache](/chapters/BP_104_fr.md)
* [Apache Vhost : désactiver le AllowOverride](/chapters/BP_105_fr.md)
* [Désactiver les logs binaires](/chapters/BP_106_fr.md)
* [Compresser les documents](/chapters/BP_107_fr.md)
* [Optimiser les PDF](/chapters/BP_108_fr.md)
* [Limiter les e-mails lourds et redondants](/chapters/BP_109_fr.md)
* [N'utiliser que des fichiers double opt-in](/chapters/BP_110_fr.md)
* [Limiter la taille des e-mails envoyés](/chapters/BP_111_fr.md)
* [Adapter les sons aux contextes d'écoute](/chapters/BP_112_fr.md)
* [Adapter les textes au web](/chapters/BP_113_fr.md)
* [Adapter les vidéos aux contextes de visualisation](/chapters/BP_114_fr.md)
* [Limiter les outils d'analytics et les données collectées](/chapters/BP_4001_fr.md)
* [Limiter l'utilisation des GIFs animés](/chapters/BP_4002_fr.md)
* [Éviter la lecture et le chargement automatique des vidéos et des sons](/chapters/BP_4003_fr.md)
* [Utiliser les compartiments CSS](/chapters/BP_4004_fr.md)
* [Fournir une alternative textuelle aux contenus multimédias](/chapters/BP_4005_fr.md)
* [Privilégier HTTP/2 à HTTP/1](/chapters/BP_4006_fr.md)
* [Économiser de la bande passante grace à un ServiceWorker](/chapters/BP_4007_fr.md)
* [Mettre en place un sitemap efficient](/chapters/BP_4008_fr.md)
* [Assurer la compatibilité avec les plus anciens appareils et logiciels du parc](/chapters/BP_4009_fr.md)
* [Réduire le volume de données stockées au strict nécessaire](/chapters/BP_4011_fr.md)
* [Mettre en place une politique d'expiration et suppression des données](/chapters/BP_4012_fr.md)
* [Limiter le recours aux canvas](/chapters/BP_4013_fr.md)
* [S'assurer que les parcours utilisateurs permettent de réaliser leur action prévue](/chapters/BP_4014_fr.md)
* [Avoir un titre de page et une metadescription pertinents avec le contenu de la page](/chapters/BP_4015_fr.md)
* [Utiliser la version la plus récente du langage](/chapters/BP_4016_fr.md)
* [Ne charger des données/du code que lorsqu'elles sont/il est nécessaire](/chapters/BP_4017_fr.md)
* [Éliminer les fonctionnalités non utilisées](/chapters/BP_4018_fr.md)
* [Préférer une PWA à une application mobile native similaire au site web](/chapters/BP_4019_fr.md)
* [Éviter les temps de blocages par des traitements JavaScript trop longs](/chapters/BP_4020_fr.md)
* [Mettre en place une architecture élastique](/chapters/BP_4021_fr.md)
* [Limiter le nombre d'appels aux API HTTP](/chapters/BP_4022_fr.md)
* [Limiter le recours aux carrousels](/chapters/BP_4030_fr.md)
* [Avoir une stratégie de fin de vie des contenus](/chapters/BP_4031_fr.md)
* [Mettre en place un "Circuit breaker"](/chapters/BP_4032_fr.md)
* [Favoriser le "Request collapsing"](/chapters/BP_4033_fr.md)
* [Sappuyer sur les services managés](/chapters/BP_4034_fr.md)
* [Préférer la pagination au défilement infini](/chapters/BP_4035_fr.md)
* [Entretenir son site régulièrement](/chapters/BP_4036_fr.md)
* [Limiter le nombre d'extensions dans un CMS](/chapters/BP_4037_fr.md)
* [Sécuriser l'accès à l'administration](/chapters/BP_4038_fr.md)
* [Ne pas afficher les documents à l'intérieur des pages](/chapters/BP_4039_fr.md)
## Licence
Les sources et contenus de ce projet sont [protégés](LICENCE.md)

43
chapters/MBP_001_fr.md Normal file
View File

@ -0,0 +1,43 @@
## Éliminer les fonctionnalités non essentielles
### Identifiants
Bonne pratique originale : [BP_001](https://github.com/cnumr/best-practices/blob/main/chapters/BP_001_fr.md)
### Catégories
| Cycle de vie | Tiers | Responsable |
|:---------:|:----:|:----:|
| 1. Spécification | Utilisateur/Terminal | PO/AMOA |
### Indications
| Degré de priorité | Mise en oeuvre | Impact écologique |
|:-------------------:|:-------------------------:|:---------------------:|
| 5 | 4 | 5 |
|Ressources Economisées |
|:----------------------------------------------------------:|
|Processeur / Mémoire vive / Stockage / Réseau / Requêtes |
### Description
Plusieurs études (Cast Software et Standish Group, notamment) démontrent que 70 % des fonctionnalités demandées par les utilisateurs ne sont pas essentielles et que 45 % ne sont jamais utilisées. En réduisant la couverture et la profondeur fonctionnelle de lapplication, on abaisse son coût de développement initial, sa dette technique et les impacts environnementaux associés.
On diminue ainsi mécaniquement linfrastructure nécessaire à son exécution. Par ailleurs, à niveau ergonomique constant, plus lapplication est pauvre fonctionnellement, plus elle sera simple à utiliser. Il faut donc réduire le plus possible la couverture fonctionnelle de lapplication, en la centrant sur le besoin essentiel de lutilisateur.
Détecter une fonctionnalité non essentielle est possible au moment de l'analyse de l'expression du besoin. La méthode MoSCoW, des ateliers, des wireframes (maquettes fonctionnelles) ou des prototypes avec tests utilisateurs permettent de vérifier l'utilité dune fonctionnalité en amont de son développement.
### Exemple
Les succès récents du Web Google, Twitter, WhatsApp, Pinterest, Instagram, etc. fournissent un seul service et misent sur une grande sobriété fonctionnelle.
Se poser, au moment de l'analyse de l'expression du besoin, la question : « Que se passe-t-il si on ne la pas ? ».
Respecter le principe YAGNI (You Ain't Gonna Need It) de lextreme programming : développez quand vous avez effectivement besoin dune fonctionnalité, pas lorsque vous imaginez en avoir besoin.
### Principe de validation
| Le nombre ... | est inférieur ou égal à |
|-------------------|:-------------------------:|
| de fonctionnalités dont l'utilité n'a pas été vérifiée avec un panel d'utilisateurs avant développement | 0 % |

49
chapters/MBP_002_fr.md Normal file
View File

@ -0,0 +1,49 @@
## Quantifier précisément le besoin
### Identifiants
Pratique originale : [BP_002](https://github.com/cnumr/best-practices/blob/main/chapters/BP_002_en.md)
### Catégories
| Cycle de vie | Tiers | Responsable |
|:---------:|:----:|:----:|
| 1. Spécification | Utilisateur/Terminal | PO/AMOA |
### Indications
| Degré de priorité | Mise en oeuvre | Impact écologique |
|:-------------------:|:-------------------------:|:---------------------:|
| 5 | 4 | 5 |
|Ressources Economisées |
|:----------------------------------------------------------:|
|Processeur / Mémoire vive / Stockage / Réseau / Requêtes |
### Description
Les « dimensions » de chaque fonctionnalité doivent être définies précisément et dans leur ensemble. Il peut sagir
dun taux de compression pour les images de linterface graphique, du temps de réponse maximum pour une requête HTTP,
du nombre ditems affichés dans une liste, etc.
Plus les « dimensions » et exigences associées à chaque fonctionnalité collent au métier, plus on évite la surqualité.
La logique doit donc être inversée par rapport aux habitudes actuelles. Si une information nest pas précisée,
cest le niveau de qualité ou la quantité minimale qui est proposé. Par exemple, en labsence de précision,
le nombre ditems dune liste est limité à 5 éléments ou au nombre maximal affichable sur le plus petit écran cible de lapplication.
Les valeurs par défaut, rarement modifiées par l'utilisateur, doivent être choisies pour répondre au besoin avec un impact minimal.
### Exemple
Gain potentiel : en jouant sur le nombre ditems affichés sur la page de résultats de son moteur de recherche Bing,
Microsoft Research a démontré quil était possible de réduire jusquà 80 % linfrastructure physique (nombre de serveurs) sous-jacente.
Autre exemple : en utilisant par défaut une résolution de vidéo acceptable (480p) plutôt que maximale, on réduit la bande passante
utilisée pour la plupart des utilisateurs (qui ne changeront pas la valeur par défaut), tout en laissant la possibilité aux autres
d'augmenter la résolution s'ils en en ont le besoin.
### Principe de validation
| Le nombre ... | est égal à |
|-------------------|:-------------------------:|
| de fonctionnalités avec des dimensions supérieures au besoin | 0 |

43
chapters/MBP_003_fr.md Normal file
View File

@ -0,0 +1,43 @@
## Optimiser le parcours utilisateur
### Identifiants
Bonne pratique originale : [BP_003](https://github.com/cnumr/best-practices/blob/main/chapters/BP_003_fr.md)
### Catégories
| Cycle de vie | Tiers | Responsable |
|:---------:|:----:|:----:|
| 2. Conception | Utilisateur/Terminal | UX/UI Designer |
### Indications
| Degré de priorité | Mise en oeuvre | Impact écologique |
|:-------------------:|:-------------------------:|:---------------------:|
| 5 | 4 | 5 |
|Ressources Economisées |
|:----------------------------------------------------------:|
|Processeur / Mémoire vive / Stockage / Réseau / Requêtes |
### Description
Optimiser le parcours utilisateur consiste à diminuer le temps passé par l'utilisateur sur ses usages les plus fréquents. Dans un premier temps, cibler les parcours les plus fréquents puis optimiser leur usage : diminuer le nombre d'étapes, diminuer le nombre d'actions, supprimer l'inutile, identifier les cas d'échecs, optimiser les temps de réponse... Un parcours est bien conçu lorsque le programme se comporte exactement comme l'utilisateur l'avait imaginé.
A minima, sonder en observant son entourage utilisant le service est un bon moyen didentifier les points de friction - situations ou interactions qui contribuent à dégrader lexpérience utilisateur et à ralentir le parcours - des utilisateurs. Les tests utilisateurs permettent d'aller plus en profondeur dans la recherche de ces points de friction.
Le temps passé par l'utilisateur sur son terminal est le deuxième post en termes d'impacts environnementaux.
### Exemple
* Proposer, pour une application de grande distribution, une nouvelle commande sur la base du contenu de la précédente.
* Acheter sans inscription sur une application de type e-commerce.
* Copier/Coller son RIB directement plutôt que le télécharger puis le transférer.
* Mettre en avant les champs ou les filtres les plus utilisés.
### Principe de validation
| Le nombre de | est inférieur à ou égal à |
|-------------------|:-------------------------:|
| points de friction | 0 |

86
chapters/MBP_004_fr.md Normal file
View File

@ -0,0 +1,86 @@
## Préférer la saisie assistée à l'autocomplétion
### Identifiants
// TODO
### Catégories
| Cycle de vie | Tiers | Responsable |
|:---------:|:----:|:----:|
| 1. Spécification | Utilisateur/Terminal | PO/AMOA |
### Indications
| Degré de priorité | Mise en oeuvre | Impact écologique |
|:-------------------:|:-------------------------:|:---------------------:|
| 3 | 3 | 3 |
|Ressources Economisées |
|:----------------------------------------------------------:|
| Requêtes |
### Description
L'autocomplétion, ou complément automatique est une fonctionnalité très répandue consistant à suggérer à l'utilisateur ou utilisatrice
des résultats correspondant à sa recherche pendant sa saisie. Par exemple, un site permettant de rechercher un itinéraire
va proposer « Paris », « Lyon Part-Dieu » et « Paray le Monial » quand la personne tape « Par ».
L'implémentation de l'autocomplétion consiste à envoyer une requête au serveur à chaque caractère saisi pour récupérer les
résultats correspondants. On peut donc avoir beaucoup de requêtes effectuées et beaucoup de ressources dépensées.
Dans la mesure du possible, cette fonctionnalité est à remplacer par la saisie assistée.
Cela consiste à guider la personne utilisatrice par un ensemble dinformations et dindices :
- Présentation du format attendu en grisé dans le champ de saisie (`placeholder`)
- Texte expliquant le format attendu
- Réaction de linterface avec un message derreur ou un changement de couleur et aide textuelle lorsque la saisie est incorrecte
- etc.
Les interactions liées à la saisie assistée sont gérées localement, ce qui réduit les échanges avec le serveur.
Pour l'exemple de la recherche d'itinéraire et de la complétion des villes, il est possible, en cas d'ambiguïté, de proposer
les différents résultats après la soumission du formulaire. L'utilisateur entre une chaine de caractère, par exemple « Lens »,
soumet le formulaire, et se voit à ce moment proposées différentes options : « Lens (France) », « Lens (Belgique) »,
« Loison sous Lens ».
Si le recours à l'autocomplétion ne peut pas être évité il est possible de minimiser le nombre de requêtes avec des optimisations simples :
- Ajouter un délai de quelque dixièmes de secondes entre l'ajout d'un caractère et la requête : cela permet de ne pas déclencher de requête si l'utilisateur n'a pas terminé sa saisie.
- Limiter le nombre de résultats affichés par l'autocomplétion, priorisés par une note de pertinence
- Fixer un nombre de caractères minimal avant de chercher à compléter.
- Si la taille de la base de données le permet, effectuer l'autocomplétion côté client en utilisant un composant natif comme `AutoCompleteTextView`
- Mettre en cache les résultats des recherches avec pour clef la chaîne saisie pour moins solliciter la base de données.
- Contextualiser les résultats pour en limiter le nombre.
### Exemple
Gain potentiel : à chaque fois que lon utilise la saisie assistée pour une fonctionnalité, plutôt que lautocomplétion, on réduit le nombre de requêtes associées par un facteur 10.
### Solution alternative
Si la donnée qui est proposée à l'utilisateur est assez petite en quantité, vous pouvez l'inclure directement dans le code de l'application en utilisant le composant natif `AutoCompleteTextView`.
```xml
<AutoCompleteTextView
android:id="@+id/auto_complete_country_text_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
```
```kotlin
val COUNTRIES = arrayOf("Belgium", "France", "Italy", "Germany", "Spain")
val countriesAdapter = ArrayAdapter<String>(
this,
R.layout.simple_dropdown_item_1line,
COUNTRIES,
)
binding.autoCompleteCountryTextView.setAdapter(countriesAdapter)
```
Ce composant proposera nativement, et sans aller/retour avec le serveur, un mécanisme d'autocompletion.
### Principe de validation
| Le nombre ... | est inférieur ou égal à |
|-------------------|:-------------------------:|
| de champs en autocomplétion | 20% |

48
chapters/MBP_005_fr.md Normal file
View File

@ -0,0 +1,48 @@
## Favoriser un design simple, épuré, adapté au mobile
### Identifiants
// TODO
### Catégories
| Cycle de vie | Tiers | Responsable |
|:---------:|:----:|:----:|
| 2. Conception | Utilisateur/Terminal | UX/UI Designer |
### Indications
| Degré de priorité | Mise en oeuvre | Impact écologique |
|:-------------------:|:-------------------------:|:---------------------:|
| 4 | 3 | 4 |
|Ressources Economisées |
|:----------------------------------------------------------:|
| Processeur / Mémoire vive / Réseau |
### Description
Tout design d'interface doit être réfléchi en amont, en prenant en compte :
- les besoins de l'utilisateur (voir la bonne pratique "Optimiser le parcours utilisateur")
- les heuristiques d'ergonomie (Bastien et Scapin, Nielsen, etc.)
- les contraintes techniques
- les bonnes pratiques d'écoconception
- et les bonnes pratiques d'accessibilité
**Privilégiez un design simple et épuré réalisable sans ajout de dépendances spécifiques.**
### Exemple
// TODO je ne comprends pas bien l'exemple. Il manque une illustration ?. A reformuler
**Description :** Certains sites contiennent des images encadrées, non contrastées et non lisibles (RGAA) et créent une surcharge mentale non nécessaire (2.2. Densité Informationnelle de Scapin et Bastien). Téléchargées, elles ne sont pourtant pas visibles sur mobile (écoconception). On peut parfois soulever l'incohérence entre signalétique et colorimétrie (1.2.2. Groupement/Distinction par le Format de Scapin et Bastien).
**Recommandation :** Supprimer les images de fond et ajouter un glyphe (Préférer les glyphes aux images, bonne pratique d'écoconception) avec une colorimétrie cohérente si un groupement doit avoir lieu.
### Principe de validation
| Le nombre ... | est inférieur ou égal à |
|-------------------|:-------------------------:|
| de pages dont le design est plus chargé que nécessaire | 0 |

100
chapters/MBP_006_fr.md Normal file
View File

@ -0,0 +1,100 @@
## Optimiser la récupération des données en fonction du cycle de vie
### Identifiants
### Catégories
| Cycle de vie | Tiers | Responsable |
|:---------:|:----:|:------------------------:|
| 2. Conception | Utilisateur/Terminal | Developpeur/Développeuse |
### Indications
| Degré de priorité | Mise en oeuvre | Impact écologique |
|:-------------------:|:-------------------------:|:---------------------:|
| 3 | 4 | 3 |
| Ressources Economisées |
|:----------------------:|
| Mémoire / Réseau |
### Description
Lorsqu'une personne navigue d'une vue à une autre au sein d'une application, mais également entre plusieurs applications sur son mobile, ces vues transitionnent entre différents états. Selon ces changements d'état, pour optimiser l'usage de la mémoire du téléphone, le système va effectuer des opérations telles que : libérer partiellement la mémoire si l'application passe en arrière-plan, supprimer complétement les données de la mémoire si l'utilisateur quitte la vue en cours en appuyant par exemple sur le bouton retour. Ces changements d'état sont matérialisés par le cycle de vie.
Il convient d'optimiser l'accès aux données utilisées faites par la vue, afin d'éviter d'effectuer des requêtes en base de données locale ou sur le réseau à chaque changement d'état.
Il existe plusieurs bonnes pratiques à appliquer à différents niveaux :
- À l'échelle de la vue :
- En utilisant correctement les callbacks du cycle de vie fournies par les composants `Activity` ou `Fragment`.
- À l'échelle du `ViewModel` :
- En utilisant une classe de type `ViewModel` (par exemple via l'implémentation fournie par l'API **Jetpack ViewModel**) ayant un cycle de vie plus long.
#### A l'échelle de la vue :
Au sein d'une classe de type `Activity` ou `Fragment`, il est courant de surcharger une ou plusieurs méthodes du cycle de vie afin d'initialiser et d'adapter l'état de la vue (via les méthodes `onCreate`, `onResume`, `onPause`,`onStop`, etc.). Il est important d'éviter de récupérer inutilement les données depuis la base de données locale ou le réseau à chaque fois que la vue redevient visible et utilisable (état `RESUMED`), c'est-à-dire au sein de la fonction `onResume`.
Il convient plutôt d'initialiser l'état de la vue au sein de la fonction `onCreate` et de récupérer les données dont elle a besoin soit dans l'état `CREATED`, soit dans l'état `STARTED`.
Note : Dans certaines situations, il est conseillé de développer ses propres composants "lifecycle aware" afin d'être notifié de la même façon de ces changements d'états, afin de rendre le code plus maintenable.
#### A l'échelle du `ViewModel`
Une classe de type `ViewModel` a un cycle de vie d'une durée de vie plus longue qu'une `Activity` ou un `Fragment`.
Gérer et maintenir les données de la vue au sein de ce type de classe permet de les garder en mémoire durant toute la durée de vie de la vue. Typiquement lors des changements de configuration (ex : l'utilisateur change l'orientation de l'écran) ou lorsque la vue passe en arrière-plan. Les données dont la vue a besoin pour se restaurer suite à ces changements restent ainsi accessibles sans avoir besoin d'effectuer une nouvelle requête en base de données ou sur le serveur. L'accès en lecture et en écriture aux données en mémoire est plus rapide et moins consommateur. De plus, une fois que la vue associée au ViewModel est détruit, par exemple si l'utilisateur quitte l'écran en appuyant sur le bouton retour, le ViewModel est aussi détruit, libérant ainsi les données de la mémoire précédemment stockées.
### Exemple
Soit une vue d'une application affichant le profil d'un utilisateur :
`MainActivity.kt` :
```
class ProfileActivity : ComponentActivity() {
private val viewModel: ProfileViewModel by viewModels()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// Update the uiState
lifecycleScope.launch {
lifecycle.repeatOnLifecycle(Lifecycle.State.STARTED) {
viewModel.uiState.collectLatest {
// TODO update view
}
}
}
}
}
```
`ProfileViewModel.kt` :
```
class ProfileViewModel(userRepository: UserRepository) : ViewModel() {
val uiState: StateFlow<ProfileUIState> = userRepository.userData.map {
ProfileUIState.Success(it)
}.stateIn(
scope = viewModelScope,
initialValue = ProfileUIState.Loading,
started = SharingStarted.WhileSubscribed(5_000),
)
}
sealed interface ProfileUIState {
data object Loading : ProfileUIState
data class Success(val user: User) : ProfileUIState
}
```
### Principe de validation
| Le nombre ... | est inférieur ou égal à |
|--------------------------------------------------------------------------------------------------|:-----------------------:|
| d'écran effectuant des chargements de données à chaque fois que la vue passe dans l'état `RESUMED` | 0% |
| d'écran rechargeant l'ensemble des données lors d'un changement de configuration | 0% |
| d'écran n'utilisant pas de ViewModel ou équivalent pour maintenir l'état de la vue | 0% |

46
chapters/MBP_006bis_fr.md Normal file
View File

@ -0,0 +1,46 @@
## Mettre en pause les traitements consommateurs lorsque l'application est en arrière-plan
### Identifiants
// TODO
### Catégories
| Cycle de vie | Tiers | Responsable |
|:---------:|:----:|:------------------------:|
| 2. Conception | Utilisateur/Terminal | Developpeur/Développeuse |
### Indications
| Degré de priorité | Mise en oeuvre | Impact écologique |
|:-------------------:|:-------------------------:|:---------------------:|
| 3 | 4 | 3 |
| Ressources Economisées |
|:----------------------:|
| Mémoire / Batterie |
### Description
Lorsqu'une personne navigue entre plusieurs applications sur son mobile, ces applications basculent entre premier plan et arrière-plan. Lorsqu'une application qui effectue un traitement consommateur en mémoire passe en arrière-plan, il convient de s'appuyer sur son cycle de vie pour réduire l'impact de ce traitement sur la batterie du téléphone.
* Dans la fonction `onPause`, l'activité est toujours visible à l'écran, mais l'utilisateur ne peut plus interagir avec.
- Dans la fonction `onStop`, l'activité n'est plus visible.
Au sein de ses deux callbacks, une bonne pratique est de libérer ou d'ajuster les ressources consommatrices initialisées précédemment.
Quelques exemples de traitements consommateurs :
* L'affichage d'une animation
* La lecture d'une vidéo ou d'un son.
* L'usage des capteurs du téléphone : le GPS, le gyroscope.
* L'usage de protocol de connectivité : Bluetooth, Wifi, NFC, etc.
### Exemple
* Soit une application utilisant la position GPS du téléphone. Lorsque l'activité n'est plus visible, il faut désactiver la mise à jour de la position dans la fonction `onStop` ou si cela n'est pas possible, changer la granularité de mise à jour de la position de "fine" à "grossière".
* Soit une activité `PhotoActivity` qui utilise l'appareil photo. Lorsqu'une autre activité prend le focus sur celle-ci par exemple sous forme de modale, mais que la première activité restent visible dessous (dans l'état `PAUSED`), il faut appeler la fonction `camera?.release()` dans la callback `onPause`.
### Principe de validation
| Le nombre ... | est inférieur ou égal à |
|----------------------------------------------------------------------------------------------------------------------------------------------------------------|:-------------------------:|
| de traitement lourds pour lesquels la mémoire n'est pas libéré dans les fonctions `onPause` ou `onStop` | 0% |

41
chapters/MBP_007_fr.md Normal file
View File

@ -0,0 +1,41 @@
## Stocker localement les données de l'utilisateur
### Identifiants
// TODO
### Catégories
| Cycle de vie | Tiers | Responsable |
|:---------:|:----:|:----:|
| 3. Réalisation (fabrication / développement) | Datacenter | Architecte Logiciel/Développeur |
### Indications
| Degré de priorité | Mise en oeuvre | Impact écologique |
|:-------------------:|:-------------------------:|:---------------------:|
| 4 | 3 | 4 |
|Ressources Economisées |
|:----------------------------------------------------------:|
| Réseau / Requêtes |
### Description
Il est inutile de stocker sur le serveur des données qui n'ont de sens que pour un utilisateur donné.
Il existe différents moyens permettant de stocker ce type de données en local sur un téléphone :
* Le stockage sous forme de clé valeur, grâce par exemples aux SharedPreferences.
* Le stockage au sein de la base de données locale (via SQLite ou Room par exemple).
Lintérêt du stockage local est double. Dune part, on évite les allers-retours inutiles avec le serveur, ce qui économise des ressources et du temps de réponse.
Dautre part, comme les données sont locales, il est plus facile et plus rapide de les manipuler au sein de linterface.
Le gain potentiel est la réduction de la charge serveur, donc du nombre déquipements nécessaires (de leur empreinte environnementale et économique),
des serveurs HTTP jusquaux serveurs de base de données.
### Principe de validation
| Le nombre ... | est inférieur ou égal à |
|-------------------|:-------------------------:|
| de données statiques non stockées localement | 25% |

31
chapters/MBP_008_fr.md Normal file
View File

@ -0,0 +1,31 @@
## Déployer un Android App Bundle (AAB) plutôt qu'un APK
### Identifiants
// TODO
### Catégories
| Cycle de vie | Tiers | Responsable |
|:---------:|:-----:|:------------------------:|
| 2. Conception | Utilisateur/Terminal | Développeur/Développeuse |
### Indications
| Degré de priorité | Mise en oeuvre | Impact écologique |
|:-------------------:|:-------------------------:|:---------------------:|
| 3 | 3 | 3 |
|Ressources Economisées |
|:----------------------------------------------------------:|
| Processeur / Mémoire vive / Stockage |
### Description
Un Android App Bundle (AAB) contient tout le code compilé et les ressources d'une application, mais délègue au Google Play Store la responsabilité de générer et signer l'APK qui sera installé sur l'appareil de l'utilisateur. Celui-ci optimise ainsi l'APK en n'y incluant que les ressources nécessaires selon la configuration de l'appareil. Cela permet de réduire considérablement la taille de l'application.
### Principe de validation
| Le nombre ... | est inférieur ou égal à |
|---------------|:-------------------------:|
| d'APK déployé | 0 |

39
chapters/MBP_009_fr.md Normal file
View File

@ -0,0 +1,39 @@
## Supprimer les ressources non utilisées
### Identifiants
// TODO
### Catégories
| Cycle de vie | Tiers | Responsable |
|:---------:|:-----:|:------------------------:|
| 4. Production | Utilisateur/Terminal | Développeur/Développeuse |
### Indications
| Degré de priorité | Mise en oeuvre | Impact écologique |
|:-------------------:|:-------------------------:|:---------------------:|
| 3 | 3 | 3 |
|Ressources Economisées |
|:----------------------------------------------------------:|
| Processeur / Mémoire vive / Stockage |
### Description
Supprimer les ressources et les classes non utilisées permet de réduire la taille de l'application.
Il existe plusieurs moyens d'appliquer cela :
- Utiliser le linter inclus dans Android Studio qui détecte les ressources (`res/`) non utilisées et les supprimer manuellement.
```shell
res/layout/item_row.xml: Warning: The resource R.layout.item_row appears
to be unused [UnusedResources]
```
### Principe de validation
| Le nombre ... | est inférieur ou égal à |
|-----------------------------------------------|:-------------------------:|
| de fichier non utilisé dans le package final | 0 |

64
chapters/MBP_010_fr.md Normal file
View File

@ -0,0 +1,64 @@
## Minifier et optimiser le code
### Identifiants
// TODO
### Catégories
| Cycle de vie | Tiers | Responsable |
|:-------------:|:----:|:----:|
| 4. Production | Utilisateur/Terminal | Développeur/Développeuse |
### Indications
| Degré de priorité | Mise en oeuvre | Impact écologique |
|:-------------------:|:-------------------------:|:---------------------:|
| 4 | 3 | 4 |
| Ressources Economisées |
|:----------------------:|
| Processeur / Mémoire vive / Stockage |
### Description
Utiliser un outil de minification et d'optimisation de code permet de réduire considérable la taille de l'application.
Sur android, cet outil se décompose en quatre processus :
-La minification, qui consiste à supprimer les espaces inutiles, les commentaires, les sauts de ligne, les délimiteurs de blocs et ainsi réduire la taille de l'application finale.
- La suppression des ressources non utilisées dans notre code mais également dans les bibliothèques tierces incluses dans notre projet, par exemple si notre code n'utilise qu'une petite partie de celles-ci.
- L'obfuscation. Ce processus réduit le nom des classes et de ses membres, augmentant la sécurité et réduisant par la même occasion la taille des fichiers. Par exemple la classe : `com.monpackage.MaClass` devient une fois compilée : `a.a.B`
- L'optimisation. Ce processus inspecte et optimize le code pour supprimer le code qui n'est jamais exécutée. Par exemple il peut détecter que la branche `else` d'une condition n'est jamais empruntée, et donc la supprimer du code compilé.
Pour activer et configurer ces processus, il faut activer les paramètres `isShrinkResources` et `isMinfyEnabled` dans le fichier Gradle de l'application, dans les paramètres du build qui sera déployé. Au-delà de ses paramètres, il faut ensuite spécifier les processus qui doivent s'appliquer et sur quelles classes dans le fichier `proguard-rules.pro` du projet.
### Exemple
```kotlin
android {
buildTypes {
getByName("release") {
// Enables code shrinking, obfuscation, and optimization for the release build type
isMinifyEnabled = true
// Enables resource shrinking, which is performed by the Android Gradle plugin.
isShrinkResources = true
// Includes the default ProGuard rules files
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro"
)
}
}
...
}
```
### Principe de validation
| Le nombre ... | est inférieur ou égal à |
|------------------------------------|:-----------------------:|
| de fichiers non minifiés/optimisés | 25 |