画像
画像はアプリケーションのパフォーマンスに大きな影響を与える可能性があります。最良の結果を得るには、以下の方法で画像を最適化する必要があります。
.avif
や.webp
などの最適なフォーマットを生成する- 画面サイズに合わせて異なるサイズを作成する
- アセットが効果的にキャッシュされるようにする
これを手動で行うのは面倒です。ニーズと好みに応じて、さまざまな手法を使用できます。
Viteの組み込み処理
Viteはインポートされたアセットを自動的に処理し、パフォーマンスを向上させます。これには、CSSの url()
関数によって参照されるアセットも含まれます。ファイル名にハッシュが追加され、キャッシュされるようになります。また、assetsInlineLimit
より小さいアセットはインライン化されます。Viteのアセット処理は、画像に最もよく使用されますが、ビデオ、オーディオなどにも役立ちます。
<script>
import logo from '$lib/assets/logo.png';
</script>
<img alt="The project logo" src={logo} />
@sveltejs/enhanced-img
@sveltejs/enhanced-img
は、Viteの組み込みアセット処理に加えて提供されるプラグインです。プラグアンドプレイの画像処理を提供し、avif
や webp
などのより小さいファイル形式を提供し、レイアウトシフトを回避するために画像の固有の width
と height
を自動的に設定し、さまざまなデバイス用に複数のサイズの画像を作成し、プライバシーのためにEXIFデータを削除します。SvelteKitプロジェクトを含む、Viteベースのプロジェクトで動作します。
ビルドプラグインとして、
@sveltejs/enhanced-img
はビルドプロセス中にマシン上にあるファイルのみを最適化できます。データベース、CMS、またはバックエンドから提供されるパスなど、他の場所にある画像がある場合は、CDNから画像を動的に読み込む方法についてお読みください。警告:
@sveltejs/enhanced-img
パッケージは実験的です。1.0より前のバージョンを使用しており、マイナーバージョンのリリースごとに破壊的な変更が導入される可能性があります。
セットアップ
インストール
npm install --save-dev @sveltejs/enhanced-img
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(),
function sveltekit(): Promise<Plugin<any>[]>
Returns the SvelteKit Vite plugins.
sveltekit()
]
});
画像変換の計算コストが高いため、最初のビルドは時間がかかります。ただし、ビルド出力は ./node_modules/.cache/imagetools
にキャッシュされるため、後続のビルドは高速になります。
基本的な使い方
.svelte
コンポーネントでは、<img>
ではなく <enhanced:img>
を使用し、Viteアセットインポートパスで画像ファイルを参照します。
<enhanced:img src="./path/to/your/image.jpg" alt="An alt text" />
ビルド時に、<enhanced:img>
タグは、複数の画像タイプとサイズを提供する <picture>
でラップされた <img>
に置き換えられます。画質を落とさずに画像を縮小することしかできないため、必要な最高解像度の画像を提供する必要があります。小さいバージョンは、画像をリクエストする可能性のあるさまざまなデバイスタイプ用に生成されます。
HiDPIディスプレイ(別名Retinaディスプレイ)の場合は、2倍の解像度の画像を提供する必要があります。<enhanced:img>
は、小さいデバイスに小さいバージョンを提供することを自動的に処理します。
<enhanced:img>
にスタイルを追加する場合は、class
を追加してそれをターゲットにする必要があります。
画像の動的な選択
画像アセットを手動でインポートして、<enhanced:img>
に渡すこともできます。これは、静的画像のコレクションがあり、動的に1つを選択したり、反復処理したりする場合に役立ちます。この場合、処理したいことを示すために、以下の例のように import
ステートメントと <img>
要素の両方を更新する必要があります.
<script>
import MyImage from './path/to/your/image.jpg?enhanced';
</script>
<enhanced:img src={MyImage} alt="some alt text" />
Viteの import.meta.glob
を使用することもできます。カスタムクエリを介して enhanced
を指定する必要があることに注意してください。
<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}
固有の寸法
width
と height
は、ソース画像から推測できるためオプションであり、<enhanced:img>
タグが前処理されると自動的に追加されます。これらの属性を使用すると、ブラウザは正しい量のスペースを予約できるため、レイアウトシフトを防ぐことができます。別の width
と height
を使用したい場合は、CSSで画像のスタイルを設定できます。プリプロセッサは width
と height
を自動的に追加するため、寸法のいずれかを自動的に計算したい場合は、それを指定する必要があります。
<style>
.hero-image img {
width: var(--size);
height: auto;
}
</style>
srcset と sizes
デザインの幅をとるヒーロー画像など、大きな画像がある場合は、小さいデバイスで小さいバージョンがリクエストされるように sizes
を指定する必要があります。たとえば、1280pxの画像がある場合は、次のようなものを指定できます。
<enhanced:img src="./image.png" sizes="min(1280px, 100vw)"/>
sizes
が指定されている場合、<enhanced:img>
は小さいデバイス用に小さい画像を生成し、srcset
属性を設定します。
自動的に生成される最小の画像は幅540pxになります。より小さい画像が必要な場合、またはカスタム幅を指定したい場合は、w
クエリパラメータを使用して指定できます。
<enhanced:img
src="./image.png?w=1280;640;400"
sizes="(min-width:1920px) 1280px, (min-width:1080px) 640px, (min-width:768px) 400px"
/>
sizes
が指定されていない場合、HiDPI / Retina画像と標準解像度画像が生成されます。ブラウザが高 デバイスピクセル比 を持つデバイスに画像を表示できるように、提供する画像は表示したい解像度の2倍にする必要があります。
画像ごとの変換
デフォルトでは、拡張画像はより効率的な形式に変換されます。ただし、ぼかし、品質、フラット化、回転などの他の変換を適用することもできます。クエリ文字列を追加することで、画像ごとの変換を実行できます。
<enhanced:img src="./path/to/your/image.jpg?blur=15" alt="An alt text" />
使用可能なディレクティブの完全なリストについては、imagetoolsリポジトリを参照してください。.
CDNからの動的な画像読み込み
場合によっては、ビルド時に画像にアクセスできないことがあります。たとえば、コンテンツ管理システム内または他の場所にある可能性があります。
コンテンツ配信ネットワーク(CDN)を使用すると、これらの画像を動的に最適化でき、サイズに関してより柔軟に対応できますが、セットアップのオーバーヘッドと使用コストが発生する可能性があります。キャッシュ戦略によっては、CDNから304レスポンスを受信するまで、ブラウザはアセットのキャッシュコピーを使用できない場合があります。CDNをターゲットとするHTMLを構築すると、CDNは `User-Agent` ヘッダーに基づいて適切な形式を提供できるため、`<img>` タグを使用できます。一方、ビルド時の最適化では、複数のソースを持つ `<picture>` タグを作成する必要があります。最後に、一部のCDNは画像を遅延生成する場合があり、トラフィックが少なく、画像が頻繁に変更されるサイトではパフォーマンスに悪影響を与える可能性があります。
CDNは一般的にライブラリを必要とせずに使用できます。ただし、Svelteをサポートするライブラリがいくつかあり、使いやすくなっています。@unpic/svelte
は、多数のプロバイダーをサポートするCDNに依存しないライブラリです。Cloudinary のような特定のCDNがSvelteをサポートしている場合もあります。最後に、Svelteをサポートする一部のコンテンツ管理システム(CMS)(Contentful、Storyblok、Contentstackなど)には、画像処理の組み込みサポートがあります。
ベストプラクティス
- 画像タイプごとに、上記で説明したソリューションから適切なソリューションを使用してください。1つのプロジェクトですべての3つのソリューションを組み合わせて使用できます。たとえば、Viteの組み込み処理を使用して
<meta>
タグの画像を提供し、@sveltejs/enhanced-img
でホームページに画像を表示し、動的なアプローチでユーザーが送信したコンテンツを表示できます。 - 使用する画像の最適化タイプに関係なく、すべての画像をCDN経由で提供することを検討してください。CDNは、静的アセットのコピーをグローバルに配信することにより、レイテンシを削減します。
- 元の画像は高品質/高解像度で、HiDPI デバイスに対応するために表示される幅の 2 倍の幅を持つ必要があります。画像処理により、小さな画面に配信する際に帯域幅を節約するために画像サイズを縮小できますが、画像サイズを拡大するためにピクセルを生成するのは帯域幅の無駄です。
- ヒーロー画像など、ページデザインの幅全体を占める、モバイルデバイスの幅(約 400px)よりもはるかに大きい画像の場合は、小さなデバイスで小さな画像が配信されるように
sizes
を指定します。 - 最大コンテンツのペイント (LCP) 画像など、重要な画像の場合は、
fetchpriority="high" loading="eager"
を設定して、できるだけ早く読み込むことを優先します。 - 画像にコンテナまたはスタイルを指定して、ページの読み込み中に画像が飛び跳ねて 累積レイアウトシフト (CLS) に影響を与えないようにします。
width
とheight
は、画像の読み込み中にブラウザがスペースを確保するのに役立ちます。そのため、@sveltejs/enhanced-img
はwidth
とheight
を自動的に追加します。 - 常に適切な
alt
テキストを提供してください。指定しない場合、Svelte コンパイラは警告を出します。 sizes
にem
またはrem
を使用し、これらの測定値のデフォルトサイズを変更しないでください。sizes
または@media
クエリで使用する場合、em
とrem
はどちらもユーザーのデフォルトのfont-size
を意味するように定義されています。sizes="(min-width: 768px) min(100vw, 108rem), 64rem"
のようなsizes
宣言の場合、CSS によって変更されると、ページ上の画像のレイアウト方法を制御する実際のem
またはrem
が異なる場合があります。たとえば、html { font-size: 62.5%; }
のようにしないでください。ブラウザのプリローダーによって予約されたスロットは、CSS オブジェクトモデルが作成された後に実際のCSSオブジェクトモデルのスロットよりも大きくなってしまうためです。