Automatiser la compression et l'encodage

Intégrez facilement la génération de sources d'images hautement performantes de développement d'applications.

Toutes les syntaxes de ce cours, de l'encodage des données d'image à la densité d'informations qui alimente les images responsives, sont des méthodes permettant aux machines de communiquer avec les machines. Vous avez découvert un certain nombre de façons pour un navigateur client de communiquer ses besoins à un serveur et un serveur de répondre en genre. Le balisage d'image réactif (srcset et sizes en particulier) permet de décrire une quantité d'informations choquante de manière que quelques caractères. Le meilleur ou le pire, c'est que la brièveté est une caractéristique de conception: il s'agit de rendre ces syntaxes moins concises et faciles à utiliser pour les développeurs. peuvent être plus difficiles à analyser pour un navigateur. Plus une chaîne est complexe, plus des erreurs d'analyseur ou des différences de comportement involontaires d'un navigateur à l'autre.

Fenêtre d'encodage d'image automatisé

Cependant, le trait qui peut rendre ces sujets si intimidants peut également vous apporter des solutions: une syntaxe facilement read par les machines est une syntaxe plus facile à écrire par celles-ci. Vous avez certainement déjà rencontré de nombreux exemples encodage et compression d'images en tant qu'utilisateur du Web: toute image importée sur le Web via des plates-formes de réseaux sociaux, le contenu des systèmes de gestion de contenu (CMS), et même les clients de messagerie, passeront presque toujours par un système qui redimensionne, réencode et les compresse.

De même, que ce soit par le biais de plug-ins, de bibliothèques externes, d'outils de processus de compilation autonomes ou d'une utilisation responsable de scripts côté client, le balisage d'images réactif se prête facilement à l'automatisation.

Ce sont les deux principales préoccupations liées à l'automatisation des performances des images: la gestion de la création des images (leurs encodages, la compression, ainsi que les autres sources que vous utiliserez pour renseigner un attribut srcset et générer notre balisage visible par l'utilisateur. Dans ce module, vous découvrirez quelques approches courantes de gestion des images dans le cadre d'un workflow moderne, que ce soit en tant que la phase d'automatisation de votre processus de développement, par le biais du framework ou du système de gestion de contenu qui alimente votre site ; ou est presque entièrement éliminé par un réseau de diffusion de contenu dédié.

Automatiser la compression et l'encodage

Il est peu probable que vous vous retrouviez dans une position où vous pourriez prendre le temps de déterminer manuellement le codage et le niveau idéaux de compression pour chaque image individuelle destinée à un projet. En tant que car il est important de réduire au maximum la taille des transferts d'images , afin d'affiner des paramètres de compression et à réenregistrer d'autres sources pour chaque composant Image destiné à un site Web de production introduira un énorme goulot d'étranglement dans votre travail quotidien.

Comme vous l'avez appris en découvrant les différents formats d'image et types de compression, l'encodage le plus efficace pour une image sera toujours dicté par du contenu. Comme vous l'avez appris dans la section Images responsives, les autres tailles dont vous aurez besoin pour vos sources d'images seront les suivantes : déterminée par la position occupée par ces images dans la mise en page. Dans un workflow moderne, vous prendrez ces décisions de manière globale plutôt que individuelle, en déterminant un ensemble de valeurs par défaut raisonnables pour les images, afin de s'adapter au mieux aux contextes ils sont destinés à être utilisés.

Lorsque vous choisissez l'encodage d'un répertoire d'images photo, le format AVIF se distingue clairement en termes de qualité et de taille de transfert. mais avec une compatibilité limitée, WebP fournit une solution de remplacement moderne et optimisée. JPEG est la valeur par défaut la plus fiable. L'alternative les tailles que nous devons produire pour les images destinées à occuper une barre latérale dans une mise en page varient considérablement de celles des images pour occuper toute la fenêtre d'affichage du navigateur au niveau de nos points d'arrêt les plus élevés. Les paramètres de compression nécessitent un œil sur le floutage et de compression sur plusieurs fichiers résultants, laissant moins d'espace pour séparer chaque octet possible de chaque image en échange d'un workflow plus flexible et fiable. En résumé, vous suivrez le même processus de prise de décision que celui que vous avez que vous avez appris dans ce cours.

En ce qui concerne le traitement lui-même, il existe un grand nombre de bibliothèques de traitement d'images open source qui fournissent des méthodes de convertir, modifier et modifier des images par lots, et rivaliser sur le plan de la rapidité, de l'efficacité et de la fiabilité. Ces tâches de traitement vous permettent d'appliquer des paramètres d'encodage et de compression à des répertoires entiers d'images en une seule fois, ouvrez un logiciel de retouche d'images, et conservez les sources des images d'origine au cas où ces paramètres seraient nécessaires. d'être ajustés à la volée. Ils sont destinés à s'exécuter dans différents contextes, de l'environnement de développement local au lui-même (par exemple, l'élément ImageMin axé sur la compression pour Node.js peut être étendu à des applications spécifiques grâce à une série de plug-ins, tandis que la solution multiplate-forme ImageMagick et la solution Sharp basée sur Node.js sont livrés avec un nombre stupéfiant de fonctionnalités prêtes à l'emploi.

Ces bibliothèques de traitement d'images permettent aux développeurs de créer des outils dédiés à l'optimisation des images. dans le cadre de vos processus de développement standards. Ainsi, votre projet fera toujours référence à une image prête pour la production. sources avec le moins de frais généraux possible.

Outils et workflows de développement en local

Les exécuteurs de tâches et les bundlers comme Grunt, Gulp ou Webpack peuvent être utilisés pour optimiser les composants Image en même temps que d'autres tâches courantes liées aux performances, comme la minimisation des fichiers CSS et JavaScript. À Prenons un cas d'utilisation relativement simple: un répertoire de votre projet contient une douzaine d'images photographiques, destinés à être utilisés sur un site Web public.

Tout d'abord, vous devez assurer un encodage cohérent et efficace pour ces images. Comme vous l'avez appris dans les modules précédents, WebP est un format par défaut efficace pour les images photographiques en termes de qualité et de taille de fichier. Le format WebP est bien compatible, mais qui ne sont pas prises en charge universelle. Vous devez donc également inclure une création de remplacement sous la forme d'un fichier JPEG progressif. Ensuite, Pour utiliser l'attribut srcset et ainsi diffuser efficacement ces éléments, vous devez produire plusieurs d'autres tailles pour chaque encodage.

Bien que cette corvée soit répétitive et chronophage avec un logiciel de retouche d'image, les exécuteurs de tâches Gulp est conçu pour automatiser exactement ce type de répétition. La classe gulp-responsive , qui utilise Sharp, est l'une des options parmi d'autres qui suivent toutes le même schéma: recueillant tous les fichiers d'un répertoire source, les réencodez et les compressez selon la même "qualité" standardisée. que vous avez découvert dans Formats d'image et compression. Les fichiers obtenus sont ensuite renvoyés vers un chemin d'accès que vous définissez prêt à être référencé dans les attributs src de vos éléments img visibles par l'utilisateur tout en laissant vos fichiers d'origine intacts.

const { src, dest } = require('gulp');
const respimg = require('gulp-responsive');

exports.webp = function() {
  return src('./src-img/*')
    .pipe(respimg({
      '*': [{
        quality: 70,
        format: ['webp', 'jpeg'],
        progressive: true
      }]
  }))
  .pipe(dest('./img/'));
}

Avec un tel processus en place, aucun préjudice ne serait fait à un environnement de production si quelqu’un sur le projet par inadvertance ajouté une photo encodée au format PNG en couleurs vives dans le répertoire contenant vos sources d'images d'origine, quel que soit l'encodage de l'image d'origine, cette tâche produira un format WebP efficace et une création de remplacement JPEG progressive fiable, et à une avec un niveau de compression ajustable à la volée. Bien sûr, ce processus garantit également que l'image d'origine sont conservés dans l'environnement de développement du projet, ce qui signifie que ces paramètres peuvent être ajustés à tout temps, seule la sortie automatisée est écrasée.

Pour générer plusieurs fichiers, vous devez transmettre plusieurs objets de configuration. Une clé width et une valeur en pixels:

const { src, dest } = require('gulp');
const respimg = require('gulp-responsive');

exports.default = function() {
  return src('./src-img/*')
    .pipe(respimg({
    '*': [{
            width: 1000,
            format: ['jpeg', 'webp'],
            progressive: true,
            rename: { suffix: '-1000' }
            },
            {
            width: 800,
            format: ['jpeg', 'webp'],
            progressive: true,
            rename: { suffix: '-800' }
            },
            {
            width: 400,
            format: ['jpeg', 'webp'],
            progressive: true,
            rename: { suffix: '-400' },
        }]
        })
    )
    .pipe(dest('./img/'));
}

Dans l'exemple ci-dessus, la taille de l'image d'origine (monarch.png) était supérieure à 3,3 Mo. Le plus grand fichier généré par cette tâche (monarch-1000.jpeg) fait environ 150 Ko. Le plus petit, monarch-400.web, ne fait que 32 Ko.

[10:30:54] Starting 'default'...
[10:30:54] gulp-responsive: monarch.png -> monarch-400.jpeg
[10:30:54] gulp-responsive: monarch.png -> monarch-800.jpeg
[10:30:54] gulp-responsive: monarch.png -> monarch-1000.jpeg
[10:30:54] gulp-responsive: monarch.png -> monarch-400.webp
[10:30:54] gulp-responsive: monarch.png -> monarch-800.webp
[10:30:54] gulp-responsive: monarch.png -> monarch-1000.webp
[10:30:54] gulp-responsive: Created 6 images (matched 1 of 1 image)
[10:30:54] Finished 'default' after 374 ms

Bien entendu, vous devez examiner attentivement les résultats pour détecter des artefacts de compression visibles, ou éventuellement augmenter la compression. pour faire des économies supplémentaires. Cette tâche n'étant pas destructrice, vous pouvez facilement modifier ces paramètres.

En résumé, en échange des quelques kilo-octets que vous pourriez découper grâce à une micro-optimisation manuelle minutieuse, vous obtenez un processus Il est non seulement efficace, mais résilient : un outil qui applique facilement vos connaissances sur les composants Image hautes performances. à l'ensemble d'un projet, sans aucune intervention manuelle.

Le balisage d'images responsives en pratique

Le remplissage des attributs srcset est généralement un processus manuel simple, car les attributs ne capturent que des informations sur la configuration que vous avez déjà effectuée lors de la génération de vos sources. Dans les tâches ci-dessus, nous avons établi les noms de fichiers et les informations sur la largeur que notre attribut suivra:

srcset="filename-1000.jpg 1000w, filename-800.jpg 800w, filename-400.jpg 400w"

N'oubliez pas que le contenu de l'attribut srcset est descriptif et non normatif. Il n'y a aucun mal à surcharger srcset, à condition que le format de chaque source soit cohérent. Un attribut srcset peut contenir l'URI et la largeur de chaque coupe alternative générée par le serveur, sans engendrer de requêtes inutiles. que nous fournissons pour l'image affichée, plus le navigateur sera en mesure d'adapter les requêtes efficacement.

Comme vous l'avez appris dans la section Images responsives, vous devez utiliser l'élément <picture> pour gérer facilement le WebP. ou JPEG. Dans ce cas, vous allez utiliser l'attribut type de concert avec srcset.

<picture>
  <source type="image/webp" srcset="filename-1000.webp 1000w, filename-800.webp 800w, filename-400.webp 400w">
  <img srcset="filename-1000.jpg 1000w, filename-800.jpg 800w, filename-400.jpg 400w" sizes="…" alt="…">
</picture>

Comme vous l'avez appris, les navigateurs compatibles avec WebP reconnaissent le contenu de l'attribut type et sélectionnent ce <source> l'attribut srcset de l'élément en tant que liste d'images candidates. Navigateurs qui ne reconnaissent pas image/webp comme un contenu multimédia valide le type ignore ce <source> et utilise à la place l'attribut srcset de l'élément <img> interne.

Il faut également tenir compte d'un autre aspect concernant la compatibilité des navigateurs: les navigateurs non compatibles avec le balisage d'image réactif n'ont pas besoin d'une création de remplacement, ou l'image risque d'être endommagée, en particulier dans les anciens contextes de navigation. Parce que <picture>, <source> et srcset sont tous ignorés dans ces navigateurs, nous devons spécifier une source par défaut dans les <img> internes src.

Comme la mise à l'échelle vers le bas d'une image est visuellement fluide et que l'encodage JPEG est universellement accepté, le plus grand format JPEG est un choix judicieux.

<picture>
  <source type="image/webp" srcset="filename-1000.webp 1000w, filename-800.webp 800w, filename-400.webp 400w">
  <img src="filename-1000.jpg" srcset="filename-1000.jpg 1000w, filename-800.jpg 800w, filename-400.jpg 400w" sizes="…" alt="…">
</picture>

sizes peut être un peu plus difficile à gérer. Comme vous l'avez appris, sizes dépend nécessairement du contexte : vous ne peuvent pas renseigner l'attribut sans connaître l'espace que l'image est censée occuper dans la mise en page affichée. Pour les requêtes les plus efficaces possible, un attribut sizes précis doit figurer dans notre balisage au moment où ces requêtes sont effectuées par l'utilisateur final, bien avant que les styles qui régissent la mise en page ne soient demandés. Omission de sizes constitue non seulement une violation de la spécification HTML, mais elle entraîne un comportement par défaut équivalent à sizes="100vw" : le navigateur que cette image n'est contrainte que par la fenêtre d'affichage elle-même, ce qui permet d'obtenir les sources candidates les plus importantes possibles. sélectionné.

Comme pour toute tâche de développement Web particulièrement lourde, un certain nombre d'outils ont été créés pour éliminer le processus d'écriture manuscrite des attributs sizes. respImageLint est un champ extrait de code essentiel destiné à vérifier l'exactitude de vos attributs sizes et à fournir des suggestions d'amélioration. Il s'exécute sous la forme d'un favori intelligent, c'est-à-dire un outil que vous exécutez dans votre navigateur, tout en pointant vers la page entièrement affichée contenant votre image. éléments. Si le navigateur comprend parfaitement la mise en page, la qualité est presque irréprochable. de l'espace qu'une image est censée occuper dans cette mise en page, dans toutes les tailles de fenêtre d'affichage possibles.

Rapport sur les images responsives indiquant une différence de taille et de largeur.

Un outil d'analyse lint des attributs sizes est certes utile, mais il est encore plus utile pour les générer en gros. Comme vous le savez, la syntaxe srcset et sizes est conçue pour optimiser les demandes de composants Image de manière visuellement fluide. Bien que ne doit jamais être utilisé en production, une valeur d'espace réservé sizes par défaut de 100vw est tout à fait raisonnable. tout en travaillant sur la mise en page d'une page dans votre environnement de développement local. Une fois les styles de mise en page configurés, exécuter respImageLint vous fournira des attributs sizes personnalisés, que vous pourrez copier et coller dans votre balisage avec un niveau de détail beaucoup plus élevé. que celui écrit à la main:

Rapport sur les images responsives avec les dimensions suggérées

Bien que les requêtes d'image initiées par un balisage affiché par le serveur se produisent trop rapidement pour que JavaScript génère un attribut sizes côté client, le même raisonnement ne s'applique pas si ces requêtes sont lancées côté client. Le projet Lazysizes, Par exemple, vous pouvez différer complètement les demandes d'image jusqu'à ce que la mise en page soit établie, ce qui permet à JavaScript de générer nos valeurs sizes. Vous bénéficiez d'un très grand confort et vous avez la garantie de recevoir les requêtes les plus efficaces possible pour vos utilisateurs. Cependant, gardez à l'esprit que cette approche implique de sacrifier la fiabilité du balisage affiché par le serveur et la vitesse des optimisations intégrées dans les navigateurs, et l'envoi de ces requêtes uniquement après le rendu de la page aura un impact peut avoir un impact négatif sur votre score LCP.

Bien entendu, si vous dépendez déjà d'un framework de rendu côté client tel que React ou Vue, il s'agit d'une dette que vous devrez déjà n'est pas généré. Dans ce cas, l'utilisation de Lazysizes signifie que vos attributs sizes peuvent être presque complètement éliminés. Mieux encore: comme sizes="auto" sur les images à chargement différé obtient un consensus et mises en œuvre natives, les tailles différées deviendront un polyfill pour ce comportement de navigateur nouvellement standardisé.