シリーズ目次 / 前章: 10. AstroのエンドポイントとActions / 次章: 12. Astroのビルドとデプロイ
Table of contents
Open Table of contents
この章のねらい
Astroの速さを支えているのは、送るJavaScriptの少なさだけではありません。画像と画面遷移にも仕組みがあります。どちらも体感速度に直結する場所です。
この2つを見ていきます。設定を少し足すだけで効きます。
画像最適化
Webページの転送量は、たいてい画像が大半を占めます。ここを削るのがいちばん効きます。
Astroは astro:assets モジュールを通じて、画像の圧縮・フォーマット変換・サイズ調整を自動で行います。
画像の置き場所
第2章で触れた src/ と public/ の違いが、ここで効いてきます。
| 置き場所 | 参照方法 | 最適化 |
|---|---|---|
src/(慣例的に src/assets/) | インポートして使う | される |
public/ | URLパスを直接書く | されない |
| リモート(外部URL) | 完全なURLを書く | 設定すればされる |
最適化したい画像は src/ に置くのが基本です。public/ は、URLを固定したいファイル(OGP用の固定画像、ファビコンなど)に限定しましょう。
3つの置き場所を並べると、次のようになります。
Imageコンポーネント
---
import { Image } from "astro:assets";
import heroImage from "../assets/hero.png";
---
<Image src={heroImage} alt="海辺に立つ灯台の写真" />
これだけで、次の処理が自動的に行われます。
- WebPなど効率のよい形式への変換
widthとheightの自動設定- ファイル名へのハッシュ付与(キャッシュ制御)
width と height が自動で入るのは効きます。これがないと、画像の読み込み完了時にページのレイアウトが突然ずれる現象(CLS、Cumulative Layout Shift)が起きます。
用語: CLSは「読み込み中に表示位置が動いてしまう度合い」を示す指標です。読んでいた文章が急に下へずれる、押そうとしたボタンが移動する、といった不快な体験の原因になります。
alt 属性は必須です。省略するとビルドエラーになります。装飾目的で読み上げ不要な画像の場合は、空文字(alt="")を明示的に指定します。
レスポンシブ画像
layout プロパティを指定すると、srcset と sizes が自動生成され、端末の画面幅に応じたサイズの画像が配信されます。
<Image
src={heroImage}
layout="constrained"
width={800}
height={600}
alt="海辺に立つ灯台の写真"
/>
| 値 | 挙動 |
|---|---|
constrained | 指定サイズを上限として、画面幅に応じて縮小する |
full-width | 常に画面幅いっぱいに広げる |
サイト全体の既定値は、astro.config.mjs の image.layout で設定できます。
Pictureコンポーネント
複数のフォーマットを出し分けたい場合は <Picture /> を使います。ブラウザが対応する形式を選んで読み込みます。
---
import { Picture } from "astro:assets";
import heroImage from "../assets/hero.png";
---
<Picture
src={heroImage}
formats={["avif", "webp"]}
alt="海辺に立つ灯台の写真"
/>
新しい形式(AVIF)に対応したブラウザには軽いファイルを、非対応のブラウザには従来形式を、という出し分けが自動化されます。
通常のimgタグを使う場合
<img> タグで src/ の画像を使うときは、インポートした値のプロパティを展開します。
---
import localDog from "../assets/dog.jpg";
---
<img
src={localDog.src}
width={localDog.width}
height={localDog.height}
alt="散歩中の犬"
/>
インポート結果には src / width / height / format が含まれています。ただし最適化はかからないため、通常は <Image /> を使ってください。
プログラムから画像を扱う
エンドポイントなど、テンプレート以外の場所で画像を加工したい場合は getImage() を使います。
import { getImage } from "astro:assets";
import heroImage from "../assets/hero.png";
const optimized = await getImage({ src: heroImage, format: "avif" });
// optimized.src に最適化後のパスが入る
リモート画像
外部URLの画像も、設定で許可すれば最適化の対象にできます。astro.config.mjs で許可するドメインやパターンを指定します。
export default defineConfig({
image: {
domains: ["images.example.com"],
},
});
無条件に外部画像を処理すると、意図しない負荷や乱用につながるため、明示的な許可が必要な設計になっています。
View Transitions:滑らかな画面遷移
第1章で述べたとおり、AstroはMPAモデルを採用しています。素朴に実装すると、ページ遷移のたびに画面が白く点滅します。これを解消するのが View Transitions です。
ClientRouterを導入する
レイアウトの <head> に <ClientRouter /> を置くだけで有効になります。
---
// src/layouts/BaseLayout.astro
import { ClientRouter } from "astro:transitions";
---
<html lang="ja">
<head>
<meta charset="utf-8" />
<ClientRouter />
</head>
<body>
<slot />
</body>
</html>
これにより、サイト内のリンク遷移がクライアント側で処理され、SPAのような滑らかさが得られます。対応ブラウザではView Transition APIを利用し、非対応のブラウザでは既定でAstroがアニメーションとクライアント側遷移を模擬します。非対応ブラウザで通常のページ遷移に戻したい場合は、<ClientRouter fallback="none" /> を指定します。
遷移ディレクティブ
遷移の見え方は、要素に付けるディレクティブで調整します。
| ディレクティブ | 役割 |
|---|---|
transition:name | 遷移前後で対応する要素を明示する |
transition:animate | アニメーションの種類を指定する(fade、slide、none など) |
transition:persist | 遷移後も要素を置き換えず、状態を保持する |
transition:name は、一覧ページのサムネイルと詳細ページのメイン画像のように、同じものが位置を変えて現れる表現に使います。
<!-- 一覧ページ -->
<img src={post.image} transition:name={`hero-${post.id}`} alt={post.title} />
<!-- 詳細ページ -->
<img src={post.image} transition:name={`hero-${post.id}`} alt={post.title} />
名前が一致した要素同士が、遷移中につながって動きます。名前はページ内で一意にしてください。
transition:persist は、音楽プレイヤーや動画のように遷移をまたいで再生を止めたくない要素に使います。
<audio controls transition:persist src="/bgm.mp3"></audio>
ライフサイクルイベント
遷移の各段階でイベントが発火します。ローディング表示の制御や、テーマ設定の再適用に利用できます。
| イベント | タイミング |
|---|---|
astro:before-preparation | 次ページの読み込みを始める前 |
astro:after-preparation | 読み込みが完了した後 |
astro:before-swap | 画面を入れ替える直前 |
astro:after-swap | 入れ替えた直後 |
astro:page-load | 表示とスクリプト実行が完了した後 |
たとえば、遷移後に必ずページ先頭へスクロールしたい場合はこう書けます。
<script>
document.addEventListener("astro:after-swap", () => {
window.scrollTo({ left: 0, top: 0, behavior: "instant" });
});
</script>
導入時の注意点
View Transitionsを入れると、ページ遷移でページ全体が再読み込みされなくなります。そのため、次の点でつまずきます。
- 通常の
<script>は、遷移後のページでは自動的には再実行されません。毎回実行したい処理はastro:page-loadイベントの中に書くか、data-astro-rerun属性を付けます DOMContentLoadedを前提にした処理は、初回しか動きません- グローバルな状態(
windowに保存した値など)は遷移をまたいで残ります
外部ライブラリを組み込むときは、ここで転びます。
要点
- 最適化したい画像は
src/に置き、<Image />で表示する。altは必須である。 width/heightが自動設定されることで、読み込み時のレイアウトのずれ(CLS)を防げる。layoutプロパティでレスポンシブ画像を、<Picture />で複数フォーマットの出し分けを実現できる。<ClientRouter />をレイアウトの<head>に置くだけで、滑らかな画面遷移が有効になる。- 遷移後もスクリプトを動かすには
astro:page-loadイベントかdata-astro-rerunを使う。
参考資料
- Images — Astro Docs
- View Transitions — Astro Docs
- astro:assets API Reference — Astro Docs
- Configuration Reference — Astro Docs
シリーズ目次 / 前章: 10. AstroのエンドポイントとActions / 次章: 12. Astroのビルドとデプロイ