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 écrireenhanced\: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" />
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 évitezloading="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
etheight
aident le navigateur à réserver de la place pendant le chargement de l’image, et c’est pour cela que@sveltejs/enhanced-img
va ajouterwidth
etheight
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
ourem
danssizes
, et ne changez pas la taille par défaut de ces mesures. Lorsqu’utilisées avecsizes
ou requêtes@media
,em
etrem
sont toutes deux définies pour représenter la taille de policefont-size
par défaut de l’utilisateur ou utilisatrice. Pour des déclarationssizes
commesizes="(min-width: 768px) min(100vw, 108rem), 64rem"
, lesem
etrem
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 commehtml { 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