Amazon Web Services évolue sans cesse, publiant chaque semaine de nouveaux services et de nouvelles fonctionnalités.
J’essaie de me tenir au courant de ces nouveautés en faisant une veille active.
Une des annonces importantes cette semaine est le support de Brotli dans CloudFront.
Je vais montrer aujourd’hui comment activer la compression Brotli dans une distribution.
Avant cela je propose de revoir brièvement ce que sont CloudFront et Brotli.

CloudFront

CloudFront est le service de CDN proposé par AWS. Un CDN (Content Delivery Network) permet de redistribuer du traffic plus rapidement à des utilisateurs situés à des endroits différents. Par exemple si votre serveur web est dans la zone eu-west-3 (Paris) la latence sera élevée pour les visiteurs Canadiens. L’idée et de mettre le contenu de votre site en cache dans un emplacement situé au Canada. CloudFront s’appuie ainsi sur un réseau mondial de 217 points de présence. Il est à noter que pour un pays donné il existe plusieurs points de présence. En France il y a actuellement 5 points, avec par exemple Nantes et Marseille en plus de Paris.

Les principaux concurrents de CloudFront sont CloudFlare et Akamai. L’avantage de CloudFront est son intégration forte avec les autres services d’AWS. Il est ainsi possible de choisir comme source de sa distribution un instance EC2, un ELB ou même un bucket S3 configuré en mode hébergement de site statique. Dans le cas de ce blog, j’ai choisi cette dernière option. Cela permet en outre de rajouter le support de HTTPS qui n’est pas fourni par S3. Il est ensuite possible de rajouter une entrée DNS dans le service Route 53 afin de diriger le traffic vers la distribution CloudFront.

Brotli

Et Brotli dans tout ça ? Brotli est un algorithme de compression developpé par Google. Actuellement la plupart des échanges entre navigateurs et serveurs web utilisent du Gzip. Ceci permet de réduire drastiquement le volume des données échangées et ainsi optimiser les performances web. Brotli promet une meilleure compression et certains benchmarks confirment cette promesse avec respectivement :

  • 14% de réduction par rapport au gzip pour du JavaScript
  • 21% de réduction par rapport au gzip pour du HTML
  • 17% de réduction par rapport au gzip pour du CSS

Ceci étant dit on ne juge pas un algorithme de compression sur le seul critère du taux de compression. En effet si la réduction de la taille des fichiers va s’accompagner d’une réduction du temps nécessaire pour les transférer il faut aussi prendre en compte le temps de compression et de décompression.

Il existe une croyance selon laquelle la compression avec Brotli est plus lente qu’avec Gzip. Cela est partiellement du au fait que Brotli comme Gzip peuvent etre utilisés avec des niveaux de compressions configurables. Le niveau par défaut pour Brotli est le plus élevé, ce qui n’est pas le cas pour Gzip. Cela ce traduit par un temps d’exécution plus élevé mais aussi par une taille de fichier minimale. Le consensus actuel est que l’utilisation du niveau 4 de Brotli permet de compresser plus rapidement que Gzip tout en obtenant un fichier plus petit.

Enfin la dernière chose à prendre en compte est le support de Brotli par les navigateurs. En effet si il faut activer la compression sur le serveur il est tout aussi important que le navigateur soit en mesure de décompresser le contenu téléchargé. Un petit tour sur le site caniuse nous permet d’estimer qu’un peu plus de 93 % des utilisateurs possèdent un navigateur supportant Brotli. Dans le detail, on note que Chrome, Firefox, Safari et Edge le supporte. En revanche c’est niet pour Opera et IE.

Détail du support de Brotli par les navigateurs

Détail du support de Brotli par les navigateurs

Activer Brotli dans CloudFront

Venons-en maintenant au coeur du sujet.
Comment activer Brotli sur ma distribution CloudFront ?
Il faudra tout d’abord se rendre dans la console AWS, au niveau du service CloudFront.
Il y a un onglet Comportements.

Page d’affichage des comportement dans CloudFront

Page d’affichage des comportement dans CloudFront

Il faut alors sélectionner la ligne en cochant la case, puis cliquer sur Modifier.

Page de gestion des comportement dans CloudFront

Page de gestion des comportement dans CloudFront

En cliquant sur “Afficher les informations de la politique” on constate que seul le Gzip est activé.

Page de détail d’une politique de gestion de cache

Page de détail d’une politique de gestion de cache

Il existe deux types de politiques (policy en anglais) concernant la gestion du cache.
D’une part celles définies par Amazon. Elle sont préfixées par “Managed”.
D’autre part celles que vous définissez. C’est cela que nous allons utiliser.

Il faut maintenant revenir sur la page listant les stratégies, puis cliquer sur “Créer une stratégie de cache”.

Page de création d’une politique de gestion de cache

Page de création d’une politique de gestion de cache

Saisir un nom pour cette stratégie ainsi qu’une description.
Laissez toutes les valeurs par défaut et assurez-vous que les deux cases du bas sont cochées. Cliquez sur “Créer une stratégie de cache”.

Dernière étape, il faut retourner sur la page de comportement de la distribution CloudFront.
Il est maintenant possible de sélectionner la stratégie de cache nouvellement créée.

Page de gestion d’un comportement dans CloudFront

Page de gestion d’un comportement dans CloudFront

Il faut s’assurer que l’option “Compresser automatiquement les objets” est activée.
On sauvegarde et le tour est joué !

Vérification

Il est maintenant temps de vérifier que tout fonctionne correctement.
Avant cela je dois parler brièvement du header HTTP “accept-encoding”.
Cet en-tête, placé avec la requête, permet de définir quel sera l’encodage du contenu.
Différentes valeurs sont possibles :

  • gzip
  • deflate
  • br

Il est aussi possible d’envoyer une liste de valeurs comme par exemple “gzip, deflate, br”.
Dans ce cas les valeurs sont traitées par priorité par le serveur web.

Nous allons utiliser wget pour pouvoir modifier la valeur de l’en-tête.

Par exemple nous pouvons demander du gzip :

wget --header="accept-encoding: gzip" -S - http://www.jbleduigou.fr

La réponse obtenue confirme la prise en charge du gzip :

Connecting to www.jbleduigou.fr (www.jbleduigou.fr)|64:ff9b::de1:1967|:443... connected.
HTTP request sent, awaiting response... 
  HTTP/1.1 200 OK
  Content-Type: text/html; charset=utf-8
  Transfer-Encoding: chunked
  Connection: keep-alive
  Date: Sun, 20 Sep 2020 14:50:20 GMT
  Last-Modified: Mon, 14 Sep 2020 19:29:03 GMT
  x-amz-version-id: qJGGf2ajc.Wc6pqCmYodkhSnmaFAHpR6
  ETag: W/"964a4b48e87a609da8b72c943928e6a7"
  Server: AmazonS3
  Content-Encoding: gzip
  Vary: Accept-Encoding
  X-Cache: Miss from cloudfront
  Via: 1.1 7ed8bfca040de3b276333e3442676bf5.cloudfront.net (CloudFront)
  X-Amz-Cf-Pop: CDG3-C2
  X-Amz-Cf-Id: Zo24vrANQeNZp1QOx1vmjGC0bW-Yu6xG7jN6D4t6tsXvQqx0XePitA==
Length: unspecified [text/html]

Il est possible de faire de meme pour le brotli :

wget --header="accept-encoding: br" -S - http://www.jbleduigou.fr

Encore une fois, la réponse obtenue confirme la prise en charge du brotli :

Connecting to www.jbleduigou.fr (www.jbleduigou.fr)|64:ff9b::de1:1977|:443... connected.
HTTP request sent, awaiting response... 
  HTTP/1.1 200 OK
  Content-Type: text/html; charset=utf-8
  Transfer-Encoding: chunked
  Connection: keep-alive
  Last-Modified: Mon, 14 Sep 2020 19:29:03 GMT
  x-amz-version-id: qJGGf2ajc.Wc6pqCmYodkhSnmaFAHpR6
  Server: AmazonS3
  Content-Encoding: br
  Date: Sun, 20 Sep 2020 14:53:30 GMT
  ETag: "964a4b48e87a609da8b72c943928e6a7"
  Vary: Accept-Encoding
  X-Cache: Hit from cloudfront
  Via: 1.1 5b94f68b8669a909c688f32ce5942b2f.cloudfront.net (CloudFront)
  X-Amz-Cf-Pop: CDG3-C2
  X-Amz-Cf-Id: pHUEBwgGD0YOc_Q_oYYhlJG0ERrSYyowAVemaoNul2X7Op-GoJsIHQ==
  Age: 83254
Length: unspecified [text/html]

Pour le fun on peut télécharger trois fois le fichier. Une fois sans compression, une fois avec gzip et une dernière fois avec brotli. Le résultat est le suivant :

ls -alh
total 88
drwxr-xr-x   5 jbleduigou  staff   160B Sep 20 16:04 .
drwx------@ 81 jbleduigou  staff   2.5K Sep 20 14:49 ..
-rw-r--r--   1 jbleduigou  staff    24K Sep 14 21:29 index.html
-rw-r--r--   1 jbleduigou  staff   5.4K Sep 14 21:29 index.html.br
-rw-r--r--   1 jbleduigou  staff   5.9K Sep 14 21:29 index.html.gzip

Cela confirme une meilleure compression par le brotli.

Remarques diverses

Avant de conclure cet article j’ai quelques remarques supplémentaires.

Tout d’abord j’ai décidé d’activer à la fois le gzip et le brotli. En effet certains visiteurs peuvent avoir un navigateur ne supportant pas le brotli. Il serait dommage dans ce cas de les priver d’une compression du traffic et par conséquent de dégrader leur expérience de navigation. L’utilisation de l’en-tête susmentionné est justement fait pour cela. Permettre au client de spécifier le comportement qu’il souhaite en matière de compression.

Deuxièment il est assez suprenant que AWS ne propose pas une stratégie de cache managée qui supporte le brotli. Je ne serais pas étonné de voir dans les jours à venir une évolution dans ce domaine. Soit la stratégie “Managed-CachingOptimized” va évoluer pour intégrer le brotli. Soit une nouvelle stratégie va voir le jour pour ajouter cette possibilité.

Enfin j’ai effectué toute la configuration de mon infrastructure dans la console AWS. Ce n’est pas la meilleure des pratiques. Il est préférable en effet d’utiliser CloudFormation afin de scripter son infrastructure. C’est le fameux concept d’infrastructure as code. Cela apporte plusieurs avantages. Les templates CloudFormation représentent dès lors l’unique source de vérité des spécifications de votre infrastructure et décrivent exactement les composants du cloud que vous utilisez, comment ils sont reliés les uns aux autres et comment l’environnement entier est configuré. De plus vous pouvez espérer plus cohérence et de rapidité dans le déploiement de vos infrasctructures.

Je n’ai malheureusement pas pris le temps de le faire pour cet article.
Mais qui sait, peut-être qu’il y aura un épisode deux ?


Si vous êtes arrivé jusqu’ici, merci beaucoup d’avoir lu cet article !
Photo de couverture par Emile Perron.