11
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

MIERUNEAdvent Calendar 2024

Day 11

SvelteKitの画像管理:キャッシュ問題をViteで解消する

Last updated at Posted at 2024-12-10

はじめに

Sveltekitで画像を取り扱う際、『staticフォルダに置いた画像を変更したけどなかなかユーザーの画像が反映されない、、、』こんな経験ありませんか?
原因は『キャッシュ』かもしれません。
今回はviteの 機能を使って画像を簡単に参照するやり方をご紹介させていただきたいと思います!

前半はstaticフォルダに画像を配置するとなぜキャッシュの問題が起きやすくなってしまうのか、
後半では画像をassetsフォルダにおいてVite経由で管理する具体的なやり方について書いていきます。
なので、具体的な書き方だけ知りたい方は後半まですっ飛ばしていただければと思います!

開発環境

この記事では以下の環境を使用していますが、一般的なSvelteKitプロジェクトでも大丈夫です!

  • MacOS
  • node v20.12.2
  • svelte 4.2.19

画像が更新されない原因

冒頭でも少し触れましたが、『staticフォルダに置いた画像を変更したけどなかなか画像が反映されない、、、』こう言った現象の大きな原因はブラウザのキャッシュにあります。

ブラウザのキャッシュについて

ブラウザはページの読み込みを高速化するため、サーバーから一度取得した静的なリソースをキャッシュに保存します。
再度同じリソースが要求された際は、サーバーに問い合わせをせずに、ローカルに保存されたキャッシュを使用します。
ファイル名やパスが変更されていない場合、ブラウザはそのリソースが更新されているかどうかをチェックせず、キャッシュをそのまま使用します。

ブラウザはこの仕組みによって、画像を変更してもファイル名やパスが変更されていなかったらブラウザはキャッシュに保存された画像を表示してしまいます。
みかんの画像からりんごの画像に変更してもファイル名やパスが前のままだとユーザーに表示される画像はみかんのまま、、、みたいなことが起こってしまいます。かなしい

具体的な書き方

今回はVite経由で画像を管理することによって、ビルド時に画像にハッシュを付与してキャッシュによるトラブルを防ぐようにしていきます。
それでは、早速コードの説明から入ります!

読み込みたい画像を配置

assetsフォルダを作成し、読み込みたい画像を配置します。
私はsrc/lib/assets/imagesに画像を置きました。

src/
├── lib/
│   ├── assets/
│   │   ├── images/
│   │   │   ├── index.ts
│   │   │   ├── jaga.jpg
│   │   │   ├── mikan.jpg
│   │   │   ├── ringo.jpg

同じフォルダ内にtsファイルを作成して以下のように記載

私はsrc/lib/assets/images内にindex.tsファイルを作成して以下のコードを書きました。

index.ts
const images: Record<string, string | undefined> = import.meta.glob(
	"./*.jpg",
	{
		eager: true,
		import: "default",
	},
);

export function getImagesUrl(name: string) {
	return images[`./${name}`] || "";
}

ちなみにJavaScriptだったらこんな感じのコードになるかと思います!

index.js
const images = import.meta.glob("./*.jpg", {
	eager: true,
	import: "default",
});

export function getImagesUrl(name) {
	return images[`./${name}`] || "";
}

コードについて説明していきたいと思います。
viteに複数のモジュールをインポートするimport.meta.glob というものがあり、
それによって対象の画像をまとめてインポートしています。

こちらの設定の部分について

{
	eager: true,
	import: "default",
},

eager: true,で対象の画像をビルド時に画像が即座にインポートします。こうすることでawaitを書く手間が省けるので特に理由がなければこちらの設定をしておくでいいと思います。

import: "default"で画像のパスをデフォルトエクスポートするため、簡単に画像を利用できます。

svelteのコンポーネントやpagesファイルに以下を記載

今回は+pages.svelteに記載していきます

+pages.svelte
<script lang="ts">
	import { getImagesUrl } from '$lib/assets/images';
</script>

<div>
	<img src={getImagesUrl('mikan.jpg')} alt="ExampleImage" />
</div>

<style>
	img {
		max-width: 50%;
		height: auto;
	}
</style>

このようにすることで、
ビルド時に画像にハッシュが付与されるので、画像を変更した際はURLが変わっていなかったとしても変更が反映されるようになります。

今回のポイント

  • staticフォルダに画像を置くと、キャッシュによって変更前の画像がユーザーにずっと配信されてしまうことがある
  • assetsフォルダに画像を配置してViteのimport.meta.globでインポートすることによって画像にハッシュを付与できるため変更がすぐに反映できる
  • svgやpngなども同じ方法で画像を取り扱うことができます!

いかがでしたでしょうか?
今回の記事が少しでも読んでいただいた方のお役に立てれば幸いです!
それでは〜!!

11
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?