Limiter la consommation énergétique d'un service numérique grâce aux préférences utilisateurs

Le , par Julien Wilhelm - Écoconception

Dans la lutte contre la pollution numérique, il est de la responsabilité des éditeurs de services de faire de leur mieux pour ne pas accentuer le phénomène de renouvellement des terminaux et limiter toute forme de gaspillage énergétique. Si la résolution de ces enjeux environnementaux passe notamment par la promotion de solutions utiles et de nature efficiente, il reste un levier encore inexploré ou presque, sous-estimé dans tous les cas.

Et si, de la même manière que l’on peut concevoir “mobile-first”, il était possible d’adopter une approche dite “degraded-first” ? Et s’il était possible de prioriser ce qui apparait essentiel à l’utilisateur tout en conditionnant le superflu selon ses préférences ? Et si, pour mieux modérer la consommation énergétique de la couche applicative du web, la conception en mode dégradé devenait la norme ?

Prêt à accorder comme il se doit de l’intérêt aux préférences utilisateurs ?

Pourquoi consommer plus quand on peut consommer moins ?

Voilà une question légitime à laquelle je me dois tout d’abord de répondre.

Dans tous les domaines où l’on traite de l’écoconception, il est d’usage de dire que si l’on peut se passer de quelque chose, eh bien, il faut s’en passer !

C’est logique. Si nous acceptons qu’une poignée d’utilisateurs soit privée d’une fonctionnalité, sans doute celle-ci n’est-elle pas aussi essentielle qu’elle y parait. Il devient de fait aberrant de vouloir la maintenir à tout prix, même pour un nombre limité d’utilisateurs.

Mais force est de constater que nous ne sommes pas toujours décisionnaires. Priver les utilisateurs de fonctionnalités inutiles n’est pas toujours de notre ressort.

C’est dans ce cas de figure où nous sommes contraints d’aller trop loin que l’on peut espérer ouvrir la voie à un entre-deux. Au lieu de nous résigner à tout faire subir à l’ensemble des utilisateurs, nous pouvons nous plier au refus de certains.

Ce qui n’est déjà pas si mal.

La conception en mode dégradé

Ce terme un peu effrayant de “mode dégradé” répond en réalité à une problématique que l’on ose trop peu envisager : comment assurer les fonctionnalités essentielles d’un service numérique dans un contexte où les ressources que nous pouvons y allouer se retrouvent limitées ? À l’inverse de la démarche d’écoconception, où l’on détermine les fonctionnalités essentielles du service (et celles à ne pas inutilement développer), on réfléchira ici davantage à ce dont on peut se passer si cela devait s’avérer nécessaire.

Quelques leviers sur lesquels jouer en mode dégradé :

  • Désactiver la lecture automatique des vidéos ;
  • Se passer de celles d’arrière-plan, tout simplement ;
  • Abaisser leur qualité par défaut au minimum ;
  • Réduire d’un cran la qualité des images, voire s’en passer, tout ou en partie ;
  • Orienter le téléchargement des PDF vers des fichiers de qualité plus faible (à défaut de pouvoir directement proposer plusieurs liens pour un même fichier) ;
  • Permettre l’activation de certains services tiers à la demande (concerne surtout ceux que l’on estime devoir activer par défaut du point de vue de l’expérience utilisateur, les autres devant dans tous les cas être activables à la demande) ;
  • Etc.

Pour rappel, nous sommes dans une optique de compromis vis à vis des décideurs ; s’il est possible d’aller plus loin, pour tous, il ne faut pas s’en priver !

Se placer dans une logique de conception en mode dégradé consiste à partir du produit le plus fonctionnel possible. J’insiste : toujours penser “amélioration progressive”. Il ne s’agit pas de déconstruire un mur, mais d’ajouter au fur et à mesure chacune de ses briques.

Sous quelles conditions ?
En fonction des préférences utilisateurs, pardi !

Bonne nouvelle : l’utilisateur dispose déjà de moyens pour se faire entendre !

Et même s’il n’est pas systématiquement entendu, c’est déjà un premier pas dont nous pouvons tenir compte.

Voici quelques exemples qui exploitent la règle @media. Si vous ne connaissez pas cette règle CSS, voici la définition qu’en donne la MDN web docs :

Elle permet d’appliquer une partie d’une feuille de styles en fonction du résultat d’une ou plusieurs requêtes média (media queries). Grâce à cette règle, on peut indiquer une requête média et un ensemble de règles CSS qui s’appliquent uniquement si la requête média est vérifiée pour l’appareil, le contexte avec lequel le contenu est consulté.

Premier exemple : “prefers-color-scheme”

En CSS, la caractéristique média “prefers-color-scheme” permet d’adapter l’interface utilisateur d’un service numérique pour respecter au mieux les préférences de chacun en matière de thème clair / thème sombre.

@media screen and (prefers-color-scheme: dark) {
    main {
		background-color: #222;
		color: eee;
	}
}

Ainsi, dans l’extrait de code CSS ci-dessus, le fond de la page (contenu de l’élément “main”) sera de couleur sombre et son texte de couleur claire si le navigateur détecte une préférence utilisateur en faveur du thème sombre.

Cette préférence peut être héritée de la configuration système (OS) ou être propre au navigateur web. Pour tester son fonctionnement, sur Firefox, accéder à “about:config” depuis la barre d’adresse puis définir la valeur de la variable “layout.css.prefers-color-scheme.content-override” à :

  • 0 pour forcer l’activation du thème sombre ;
  • 1 pour forcer l’activation du thème clair ;
  • 2 pour respecter l’indication éventuelle du système ;
  • 3 pour suivre la configuration propre au navigateur.

Le site web du Référentiel Général d’Écoconception de Services Numériques (RGESN) tient compte de cette préférence : c’est donc le service idéal pour observer les changements apportés à l’interface utilisateur selon la valeur définie.

Note : à ce jour, près de 95 % des navigateurs supportent la caractéristique “prefers-color-scheme” de la règle @media (lien en anglais).

Second exemple : “prefers-reduced-motion”

En CSS, la caractéristique média “prefers-reduced-motion” permet d’adapter l’interface utilisateur d’un service numérique pour respecter au mieux les préférences de chacun en matière d’animation à l’écran.

button.cta:hover {
	background-color: rebeccapurple;
	color: #fff;
}
@media not (prefers-reduced-motion: reduce) {
	button.cta:hover {
		transform: scale(1.25) rotateZ(-2deg);
		transition: transform .125s ease;
	}
}

Dans l’extrait de code CSS ci-dessus, le survol des boutons d’appel à l’action (CTA) déclenchera un effet de zoom et de pivotement sur les éléments à condition que l’utilisateur n’ait pas déclaré sa préférence en faveur de la réduction des animations.

Cette préférence peut être héritée de la configuration système (OS) ou être propre au navigateur web. Pour tester son fonctionnement, sur Firefox, accéder à “about:config” depuis la barre d’adresse puis définir la valeur de la variable “ui.prefersReducedMotion” à 1 pour désactiver les animations.

L’intérêt ici, au-delà du respect de l’utilisateur, est d’adopter une approche où l’on applique des propriétés seulement si, et non de désactiver des propriétés selon. On se place alors une logique “d’amélioration” progressive.

À ce jour, près de 95 % des navigateurs supportent la caractéristique “prefers-reduced-motion” de la règle @media (lien en anglais).

Troisième exemple : “prefers-reduced-data”

J’en viens au sujet qui nous intéresse (oui, cet article bien traite d’écoconception de services numériques). Car si l’on peut défendre l’idée d’un thème sombre consommant moins d’énergie qu’un thème clair (pas toujours, au contraire, d’après cette étude en anglais) ou que jouer des animations est plus énergivore que si on ne les joue pas (logique), tout cela reste des gains énergétiques collatéraux.

En CSS, la caractéristique média “prefers-reduced-data” permet d’adapter l’interface utilisateur d’un service numérique pour respecter au mieux les préférences de chacun en matière d’économie de la donnée.

@media not (prefers-reduced-data: reduce) {
	/* Faire ici quelque chose d'énergivore ? */
}

Dans l’extrait de code CSS ci-dessus, “quelque chose d’énergivore” est accompli à condition que l’utilisateur n’ait pas déclaré sa préférence en faveur de la réduction de la consommation des données.

Je caricature, bien sûr, il ne s’agit de défendre des pratiques énergivores ! Le fait est que ce que nous allons ajouter dans cette règle @media est censé appeler à une surconsommation optionnelle de data.

Imaginons plutôt ceci :

main {
	background-color: #eee;
}
@media not (prefers-reduced-data: reduce) {
	main {
		background-image: url("path/to/an/optimized-img.avif");
	}
}

Dans l’extrait de code CSS ci-dessus, nous appliquons par défaut une couleur de fond à l’élément de contenu principal de la page (main). Grâce à la règle @media, nous remplaçons cette couleur de fond par une image d’arrière-plan seulement et seulement si l’utilisateur n’a pas déclaré vouloir économiser la donnée. Logique : le téléchargement de ladite image va occasionner un transfert de données supplémentaires.

Pour bien faire, l’image d’arrière-plan devrait être compressée, tenir compte des dimensions du rendu à l’écran (règles @media “min-width” complémentaires à imbriquer) et vérifier le support du navigateur en matière de formats d’image (fonction CSS “image-set”).

À titre d’exemple, cela pourrait donner lieu à ceci :

main {
	background-color: #eee;
}
@media not (prefers-reduced-data: reduce) {
	@media (min-width: 560px) {
		main {
			background-image: image-set(
				url("path/to/img-560.avif") type("image/avif"),
				url("path/to/img-560.webp") type("image/webp"),
				url("path/to/img-560.webp") type("image/png")
      		); 

		}
	}
	@media (min-width: 768px) {
		main {
			background-image: image-set(
				url("path/to/img-768.avif") type("image/avif"),
				url("path/to/img-768.webp") type("image/webp"),
				url("path/to/img-768.webp") type("image/png")
      		); 
		}
	}
}

Voilà qui commence à être intéressant.

Quelques freins à la mise en oeuvre

Comme la règle @media agit côté CSS, il est impossible d’empêcher une fonctionnalité décrite en HTML d’être chargée par ce biais (pour rappel, HTML est parsé avant CSS). En revanche, avec un peu d’astuce, il est tout à fait possible de conditionner l’exécution de code JavaScript à l’affichage d’un élément.

Démonstration !

<!-- Code HTML -->
<div id="an-optional-feature"></div>

/* Code CSS */
#an-optional-feature {
	display: none;
}
@media not (prefers-reduced-data: reduce) {
	#an-optional-feature {
		display: block;
	}
}

/* Code JavaScript */
document.body.onload = () => {
	let elm = document.getElementById('an-optional-feature');
	let elmStyles = getComputedStyle(elm);
	if(elmStyles.display !== 'none') {
		/* Enable optional feature */
	}
}

Dans l’extrait de code ci-dessus :

  1. En HTML, un conteneur vide (div) destiné à accueillir une fonctionnalité optionnelle est défini avec un attribut id “an-optional-feature” ;

  2. En CSS, ce conteneur est masqué par défaut avec la propriété “display”. Il est affiché si et seulement si l’utilisateur n’a pas déclaré de préférence en faveur de la réduction de la consommation des données ;

  3. En JavaScript enfin, une fois que la page est considérée prête, on vient récupérer la valeur de la propriété “display” de notre élément dont l’id est “an-optional-feature”.

    • Si la valeur de cette propriété est différente de “none”, c’est que le conteneur est visible. Par extension, cela signifie que l’utilisateur ne souhaite pas économiser la donnée. Nous pouvons donc maintenant activer notre fonctionnalité optionnelle.
    • Si la valeur de cette propriété vaut “none”, c’est que le conteneur est masqué. Par extension, cela signifie que l’utilisateur préfère économiser la donnée. La fonctionnalité optionnelle n’est pas activée.

Génial, non ?

Enfin, cela le serait s’il n’y avait pas un autre problème de taille.

À date de rédaction de cet article, la spécification Media Queries Level 5 (en) en est encore au stade du brouillon et il n’y a absolument aucun support pour cette formidable caractéristique média qu’est “prefers-reduced-data” (en).

Mais cela va venir.

Alors, en attendant, pour d’ores et déjà penser et coder en ce sens, on peut exploiter la règle “@supports” pour conditionner le CSS au support de la caractéristique “prefers-reduced-data”.

<!-- Code HTML -->
<div id="an-optional-feature"></div>

/* Code CSS */
@supports (prefers-reduced-data: reduce) {
	#an-optional-feature {
		display: none;
	}
	@media not (prefers-reduced-data: reduce) {
		#an-optional-feature {
			display: block;
		}
	}
}

/* Code JavaScript */
document.body.onload = () => {
	let elm = document.getElementById('an-optional-feature');
	let elmStyles = getComputedStyle(elm);
	if(elmStyles.display !== 'none') {
		/* Enable optional feature */
	}
}

Grâce à l’approche ci-dessus, le code est fonctionnel à date (l’élément n’est pas masqué, la fonctionnalité optionnelle est chargée), mais saura tenir compte des préférences de l’utilisateur lorsque le support sera effectif.

“Save-data” : un en-tête dédié à l’économie d’énergie

Nous avons vu comment agir côté client pour modeler la consommation énergétique d’un service selon les attentes de l’utilisateur grâce à la règle @media. C’est un bon départ, mais je le rappelle, cette technique souffre d’une limitation importante : quand CSS est appliqué, le mal est déjà fait côté HTML. Nous pouvons détricoter certaines choses. Cela ne sera ni suffisant ni performant.

C’est là qu’intervient l’en-tête HTTP “Save-data” !

Les en-têtes HTTP permettent de conditionner l’échange de ressources entre clients et serveurs. Quand le navigateur web cherche par exemple à accéder à une ressource de type image, il précise les différents formats qu’il supporte pour ce type de contenu ; au serveur ensuite d’adapter sa réponse en fonction.

L’en-tête HTTP “Save-data” est une indication du navigateur web qui, quand elle est définie avec la valeur “on”, traduit que l’utilisateur souhaite réduire la donnée. À noter que le serveur, comme toujours, reste libre d’en tenir compte ou non dans la réponse qu’il va apporter.

Mais alors :

  1. Côté utilisateur : comment demander au navigateur web de définir cet en-tête afin d’indiquer aux services notre volonté de réduire la donnée ?
  2. Côté serveur : comment tenir compte d’une telle indication ?

Si vous êtes utilisateur, renseignez-vous sur les options “d’économies de données” intégrées à certains navigateurs ; elles font déjà le travail ! Vous pouvez aussi installer une WebExtension qui injecte cet en-tête, comme Save-Data: on.

Si vous êtes développeur (en back-end), vérifiez l’existence de l’en-tête, sa valeur, et le tour est joué. Voici à quoi cela pourrait ressembler en PHP (fonctionne sous Apache2 et NGINX), logique que l’on peut aisément reproduire avec son langage back-end préféré :

<?php

$headers = apache_request_headers();

if(isset($headers['Save-Data']) && $headers['Save-Data'] === 'on') {
    # La magie peut opérer ici, en retravaillant des liens, en précisant des configurations, etc.
}
else {
    # Ou ici, selon votre façon de voir les choses. 
}

L’avenir est-il à la conception en mode dégradé ?

Quand on récapitule :

  • Côté CSS et “prefers-reduced-data”, la règle “@supports” permet de garantir un fonctionnement à toute épreuve ;
  • Côté serveur et “Save-Data”, aux développeurs back-end d’établir des points de contrôle (si l’attribut “Save-Data” existe ET si sa valeur est “on”, faire ceci, sinon faire cela) ;

Il apparait, à date de rédaction de cet article, que la difficulté n’est pas technique pour les éditeurs souhaitant s’engager dans la conception en mode dégradé de leur service numérique. Le vrai tour de force consiste à isoler le nécessaire du superflu, un peu comme dans une démarche d’écoconception.

Toutefois, qui peut vraiment à ce jour bénéficier du mode dégradé mis à disposition le cas échéant ? Plus précisément : qui sait comment indiquer sa volonté en ce sens ? Préférence “prefers-reduced-data” ou en-tête “Save-Data”, il y a fort à parier que peu d’utilisateurs lambda peuvent activer par eux-mêmes ce type d’indicateurs.

Soit ! En attendant que cela évolue, et si le navigateur le faisait pour eux ? Et si, dans des conditions où le réseau est plus faible, le navigateur avait la possibilité d’envoyer de lui-même de telles informations pour espérer d’un serveur qui lui envoie une réponse adaptée ?

Conjecture ou avenir : à vous de décider !

En attendant, emparons-nous du sujet et donnons-lui de la visibilité afin d’encourager son adoption par tous.