Skip to content
Cloud AI エンジニア入門ガイド
Go back

11. Astroの画像最適化とView Transitions

この章の全体像として、画像の置き場所、ずれを防ぐ、レスポンシブ、View Transitionsの4つを番号順に並べ、速さと体験の両方を整えられるようになることを示した図

シリーズ目次前章: 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つの置き場所を並べると、次のようになります。

srcに置いてインポートする画像は最適化され、publicに置いてURLで参照する画像は最適化されず、リモートの画像は設定すれば最適化されるという三つの選択肢を並べて比較した図

Imageコンポーネント

---
import { Image } from "astro:assets";
import heroImage from "../assets/hero.png";
---

<Image src={heroImage} alt="海辺に立つ灯台の写真" />

これだけで、次の処理が自動的に行われます。

widthheight が自動で入るのは効きます。これがないと、画像の読み込み完了時にページのレイアウトが突然ずれる現象(CLS、Cumulative Layout Shift)が起きます。

用語: CLSは「読み込み中に表示位置が動いてしまう度合い」を示す指標です。読んでいた文章が急に下へずれる、押そうとしたボタンが移動する、といった不快な体験の原因になります。

alt 属性は必須です。省略するとビルドエラーになります。装飾目的で読み上げ不要な画像の場合は、空文字(alt="")を明示的に指定します。

レスポンシブ画像

layout プロパティを指定すると、srcsetsizes が自動生成され、端末の画面幅に応じたサイズの画像が配信されます。

<Image
  src={heroImage}
  layout="constrained"
  width={800}
  height={600}
  alt="海辺に立つ灯台の写真"
/>
挙動
constrained指定サイズを上限として、画面幅に応じて縮小する
full-width常に画面幅いっぱいに広げる

サイト全体の既定値は、astro.config.mjsimage.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アニメーションの種類を指定する(fadeslidenone など)
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:nameを付けると、遷移中に同じものが位置と大きさを変えて動くようにつながることを、二つのページを並べて示した図

transition:persist は、音楽プレイヤーや動画のように遷移をまたいで再生を止めたくない要素に使います。

<audio controls transition:persist src="/bgm.mp3"></audio>

ライフサイクルイベント

遷移の各段階でイベントが発火します。ローディング表示の制御や、テーマ設定の再適用に利用できます。

リンククリックからbefore-preparation、after-preparation、before-swap、after-swap、page-loadの順にイベントが発火する遷移の流れを示した図

イベントタイミング
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が再実行されない、DOMContentLoadedが初回しか動かない、windowのグローバル状態が残るという3つの影響が生じ、それぞれ対処が必要になることを示した図

要点

参考資料


シリーズ目次前章: 10. AstroのエンドポイントとActions次章: 12. Astroのビルドとデプロイ


Share this post:

Previous Post
12. Astroのビルドとデプロイ
Next Post
10. AstroのエンドポイントとActions