Skip to main content

Images

Les images peuvent avoir un gros impact sur les performances de votre application. Pour obtenir de meilleurs résultats, vous devriez optimiser vos images en faisant les choses suivantes :

  • générer des formats optimaux comme .avif et .webp
  • créer des tailles différentes pour des écrans différents
  • vous assurez que les assets soient mis en cache de manière efficace

Faire tout cela manuellement est fastidieux. Il existe plusieurs techniques dont vous pouvez vous servir, en fonction de vos besoins et préférences.

La gestion intégrée de Vite

Vite va automatiquement traiter les assets importés pour obtenir de meilleures performances. Ceci inclut des assets référencés via la fonction CSS url(). Les hashes seront ajoutés aux noms de fichier afin qu’ils mis en cache, et les assets plus petit que assetsInlineLimit seront inlinés. La gestion des assets de Vite est le plus souvent utilisée pour les images, mais peut également être utile pour les vidéos, l’audio, etc.

<script>
	import logo from '$lib/assets/logo.png';
</script>

<img alt="Le logo du projet" src={logo} />

@sveltejs/enhanced-img

@sveltejs/enhanced-img est un plugin venant se superposer à la gestion d’assets intégrée de Vite. Il fournit un traitement d’images clé en main qui permet de servir des formats d’image comme avif ou webp, de définir automatiquement les largeur et hauteur (width et height) des images pour éviter des sauts de layout, de créer des images de différentes tailles pour des appareils différents, et de supprimer les données EXIF pour protéger la vie privée. Il fonctionne avec tout projet basé sur Vite, incluant mais ne se limitant pas aux projets SvelteKit.

En tant que plugin, @sveltejs/enhanced-img peut uniquement optimiser des fichiers situés sur votre machine pendant le processus de compilation. Si vous avez une image qui se trouve ailleurs (comme par exemple en tant que chemin servi depuis votre base de données, CMS, ou backend), merci de lire la section comment charger des images dynamiquement depuis un CDN.

Installation

Installez le paquet :

npm install --save-dev @sveltejs/enhanced-img

Ajustez le fichier vite.config.js:

import { function sveltekit(): Promise<Plugin<any>[]>

Returns the SvelteKit Vite plugins.

sveltekit
} from '@sveltejs/kit/vite';
import { function enhancedImages(): Promise<Plugin[]>enhancedImages } from '@sveltejs/enhanced-img'; import { function defineConfig(config: UserConfig): UserConfig (+3 overloads)

Type helper to make it easier to use vite.config.ts accepts a direct {@link UserConfig } object, or a function that returns it. The function receives a {@link ConfigEnv } object.

defineConfig
} from 'vite';
export default function defineConfig(config: UserConfig): UserConfig (+3 overloads)

Type helper to make it easier to use vite.config.ts accepts a direct {@link UserConfig } object, or a function that returns it. The function receives a {@link ConfigEnv } object.

defineConfig
({
UserConfig.plugins?: PluginOption[] | undefined

Array of vite plugins to use.

plugins
: [
function enhancedImages(): Promise<Plugin[]>enhancedImages(), // doit être exécuté avant le plugin SvelteKit++ function sveltekit(): Promise<Plugin<any>[]>

Returns the SvelteKit Vite plugins.

sveltekit
()
] });

La compilation va prendre plus de temps la première fois à cause du coût du calcul des transformations d’images. Cependant, les sorties de compilation vont être mises en cache dans le dossier ./node_modules/.cache/imagetools de sorte que les compilations suivantes seront plus rapides.

Usage de base

Ce paquet est à utiliser dans vos composants .svelte en instanciant <enhanced:img> plutôt que <img> et en référençant le fichier d’image avec un chemin d’import d’asset Vite :

<enhanced:img src="./path/to/your/image.jpg" alt="Un texte alternatif" />

Lors de la compilation, votre balise <enhanced:img> sera remplacée par une balise <img> entourée d’une balise <picture> fournissant plusieurs tailles et types d’images. Il est uniquement possible de réduire les tailles d’image sans perdre en qualité, ce qui signifie que vous devriez fournir la plus haute résolution d’image nécessaire — les versions plus petites seront générées pour les différents types d’appareils qui pourraient requêter votre image.

Vous devriez fournir votre image à une résolution 2x pour les moniteurs HiDPI (aussi connus en tant que écrans retina). <enhanced:img> va automatiquement se charger de servir des versions plus petites aux appareils plus petits.

Si vous souhaitez utiliser un sélecteur CSS de nom de balise dans votre bloc <style>, vous devrez écrire enhanced\:img pour échapper le : dans le nom de la balise.

Choisir une image dynamiquement

Vous pouvez également importer manuellement un asset d’image et le passer à une balise <enhanced:img>. Cela sert lorsque vous avez une collection d’images statiques et souhaitez dynamiquement en choisir une, ou bien itérer sur cette collection. Dans ce cas vous aurez besoin de mettre à jour à la fois les déclarations d’import et l’élément <img> comme montré ci-dessous afin d’indiquer que vous souhaitez les traiter.

<script>
	import MyImage from './path/to/your/image.jpg?enhanced';
</script>

<enhanced:img src={MyImage} alt="du texte alternatif" />

Vous pouvez aussi utiliser la fonctionnalité de Vite import.meta.glob. Notez que vous devrez préciser enhanced via une custom query :

<script>
	const imageModules = import.meta.glob(
		'/path/to/assets/*.{avif,gif,heif,jpeg,jpg,png,tiff,webp,svg}',
		{
			eager: true,
			query: {
				enhanced: true
			}
		}
	)
</script>

{#each Object.entries(imageModules) as [_path, module]}
	<enhanced:img src={module.default} alt="some alt text" />
{/each}

Dimensions intrinsèques

Les largeur width et hauteur height sont optionnelles puisqu’elles peuvent être inférées de l’image source et seront automatiquement ajoutées lors du pré-traitement de <enhanced:img>. Avec ces attributs, le navigateur peut réserver l’espace nécessaire aux bonnes dimensions, évitant ainsi les décalages de layout (CLS). Si vous souhaitez utiliser une width et height différentes, vous pouvez ajouter du style à l’image via CSS. À cause du fait que le préprocesseur ajouter une width et height pour vous, si vous souhaitez que l’une de ces dimensions soit automatiquement calculée, vous devrez alors le préciser :

<style>
	.hero-image img {
		width: var(--size);
		height: auto;
	}
</style>

srcset et sizes

Si vous avec une image de grande taille, comme une image de type “hero” prenant toute la largeur du design, vous devriez préciser l’attribut sizes afin que de plus petites versions soient requêtées sur des appareils plus petits. Par ex., si vous avez une image faisant 1280px de large, vous pourriez vouloir spécifier quelque chose comme :

<enhanced:img src="./image.png" sizes="min(1280px, 100vw)"/>

Si sizes est spécifié, <enhanced:img> va générer de petites images pour les petits appareils et remplir l’attribut srcset.

La plus petite image générée automatiquement aura une largeur de 540px. Si vous souhaitez des images plus petites, ou si vous voulez préciser des largeurs personnalisées, vous pouvez le faire en utilisant le paramètre de requête w :

<enhanced:img
  src="./image.png?w=1280;640;400"
  sizes="(min-width:1920px) 1280px, (min-width:1080px) 640px, (min-width:768px) 400px"
/>

Si sizes n’est pas fourni, une image HiDPI/Retina et une image de résolution standard seront générées. L’image que vous devez fournir devrait avoir une résolution 2x plus élevée que celle que vous souhaitez afficher afin que le navigateur puisse afficher cette image sur des appareils avec un grand radio de pixels.

Transformations image par image

Par défaut, les images améliorées seront transformées en des formats plus efficaces. Cependant, vous pourriez vouloir appliquer d’autres transformations telles que des opérations de flou, de qualité, d’applatissement ou de rotation. Vous pouvez exécuter des transformations image par image en ajoutant des paramètre de requête :

<enhanced:img src="./path/to/your/image.jpg?blur=15" alt="Du texte alternatif" />

Voir le code de imagetools pour obtenir la liste complète des transformations possibles et leurs directices.

Charger des images dynamiquement depuis un CDN

Dans certains cas, les images peuvent ne pas être accessibles au moment de la compilation — c-à-d qu’elles peuvent être situées dans un système de gestion de contenu ou quelque part ailleurs.

Utiliser un CDN peut vous permettre d’optimiser ces images dynamiquement, et vous fournit plus de flexibilité concernant les tailles, mais cela peut impliquer une mise en place supplémentaire et des coûts liés à l’usage. Selon la stratégie de cache, le navigateur peut ne pas être capable d’utiliser une copie en cache de l’asset tant qu’une réponse 304 n’a pas été reçue du CDN. Construire du HTML ciblant des CDNs permet d’utiliser des balises <img> puisqu’un CDN est capable de servir des images au format approprié selon l’en-tête User-Agent, alors que des optimisations à la compilation permettent de produire des balise <picture> ayant plusieurs sources. Enfin, certains CDNs peuvent générer des images en différé, ce qui peut avoir un impact négatif sur les performances pour des sites à faible trafic mais ayant des images changeant souvent.

Les CDNs peuvent être en général utilisé sans aucune librairie. Toutefois, il existe un certain nombre de librairies supportant Svelte pour rendre leur usage plus facile. @unpic/svelte est une librairie CDN-agnostic supportant un grand nombre de fournisseurs. Certains fournisseurs de CDNs comme Cloudinary supportent Svelte. Enfin, certains CMS supportant Svelte (comme Contentful, Storyblok, et Contentstack) ont un support intégré pour la gestion des images.

Bonnes pratiques

  • Pour chaque type d’image, utilisez la solution appropriée parmi celle discutées ci-dessus. Vous pouvez mélanger les trois solutions au sein du même projet. Par exemple, vous pourriez utiliser la gestion intégrée de Vite pour fournir les images des balise <meta>, afficher les images de votre page d’accueil avec @sveltejs/enhanced-img, et afficher le contenu soumis par l’utilisateur ou l’utilisatrice avec une approche dynamique.
  • Envisager de servir toutes vos images via CDN indépendamment du type d’optimisation que vous utilisez. Les CDNs réduisent la latence en distribuant des copies de vos assets statiques de manière globale.
  • Vos images d’origine devrait être de bonne qualité avec une bonne résolution et avoir 2x la largeur prévue pour son affichage afin de gérer les appareils HiDPI. Le traitement des images peut réduire la taille des images pour économiser de la bande passante lorsque vous servez des appareils avec des écran plus petits, et cela serait un gâchis de bande passante d’inventer des pixels pour agrandir les images.
  • Pour les images qui sont bien plus grandes que la largeur d’un appareil mobile (environ 400px), comme les images “hero” prenant toute la largeur du design de page, précisez l’attribut sizes afin que de plus petites images soient servies pour les plus petits appareils.
  • Pour les images importantes, comme l’image responsable du LCP, définissez les attributs fetchpriority="high" et évitez loading="lazy" pour prioriser leur chargement dès que possible.
  • Donnez à l’image un conteneur ou du style permettant qu’elle soit contrainte et ne provoque pas des sauts visuels lors du chargement de la page, ce qui affecterait votre CLS. Les attributs width et height aident le navigateur à réserver de la place pendant le chargement de l’image, et c’est pour cela que @sveltejs/enhanced-img va ajouter width et height pour vous.
  • Fournissez toujours un texte alt de bonne qualité. Le compilateur de Svelte vous avertira si vous ne le faites pas.
  • N’utilisez pas les unités em ou rem dans sizes, et ne changez pas la taille par défaut de ces mesures. Lorsqu’utilisées avec sizes ou requêtes @media, em et rem sont toutes deux définies pour représenter la taille de police font-size par défaut de l’utilisateur ou utilisatrice. Pour des déclarations sizes comme sizes="(min-width: 768px) min(100vw, 108rem), 64rem", les em et rem qui contrôlent pour de vrai la manière dont l’image est disposée sur la page peuvent être différents si modifiés via CSS. Par exemple, ne faites pas quelque chose comme html { font-size: 62.5%; } car la place réservée par le préchargement du navigateur va alors être plus grande que la vraie place que l’objet CSS prend une fois créé.

Modifier cette page sur Github llms.txt

précédent suivant