Astroのクライアントディレクティブとは?初期表示を爆速にする基礎知識

Astroのクライアントディレクティブって何?
アイランドアーキテクチャに関する記事にて、動的に機能する要素に付与する属性として、クライアントディレクティブがあるということに言及している。実際に自分が作成したサイトのコードを例として出しつつ、概要を説明したが、そこまで深い話はできていない。
繰り返しになるがまずは、その概要を説明したい。まずアイランドアーキテクチャとは(詳細はこちらの記事を参照)、JavaScriptで動作する部分を追加する機能である。
---
import PageLayout from 'PageLayout.astro';
import PageHeading from 'PageHeading.astro';
import GameList from 'GameList.vue';
---
<PageLayout
title="ゲーム一覧"
description="制作したゲームの一覧です。使用技術・制作期間・リンクを掲載しています。"
>
<div class="container-narrow py-12 pb-0">
<PageHeading title="ゲーム一覧" class="mb-8" />
<p class="text-main-muted mb-10">
完成品と開発過程をブログ形式で掲載。GitHub・プレイ動画などへのリンクも用意しています。
</p>
</div>
<GameList client:load />
</PageLayout>
上記は本サイトのゲーム一覧ページの実際のソースコードの一部改訂版である。議題に上がっているクライアントディレクティブは、<GameList client:load /> の client:load の部分のことであり、これには以下に示す表の5種類がある。
client:loadclient:idleclient:visibleclient:media="(max-width: 768px)"client:only="vue"
この5種類の使い分けを深掘りし、使い分けができるようになることを本記事の目標としたい。
5つのクライアントディレクティブの違い
5つのクライアントディレクティブはそれぞれ、優先度が異なる。この優先度に応じて、ブラウザが画面上に描画するタイミングが変わってくる。優先度が低ければタイミングは遅く、逆に高ければタイミングは早くなる。また、指定できるオプションも異なってくるため、時と場合に応じた使い分けが必要になる。
load
優先度: 高 、ページが表示された際に最優先で読み込まれる。つまりユーザー体験として、画面を表示して一番最初に表示されるべき部品には、loadを用いる。例えば、サイト上部に表示されるグローバルナビゲーションやタイトルといった部分がそれに当たる。
ただし、loadが割り振られた部品が多くなりすぎた場合、初期表示に時間がかかる。そのため 本当に 素早く表示したい部品のみ、loadにすべきだろう。とはいえ画面に表示する部品が少ない場合、基本的に全てloadで問題ない。表示が速いに越したことはない。
idle
優先度: 中 、ページの初期表示が終わり、ブラウザのメインスレッドが空いた(アイドル状態になった)タイミングで読み込まれる。画面のファーストビューには存在しているけれど、すぐにはクリックされないタブボタンなどで、こちらを利用する。
visible
優先度: 低 、対象の部品が画面上に表示されたタイミングで読み込まれる。画面をスクロールして下の方まで移動しないと表示されないボタンなどに利用する。もしもユーザーがスクロールさせなかった場合は読み込まれないため、初期表示に存在しない場合などは決して操作性の邪魔にならないのが強みだ。
media
優先度: 条件次第、条件として指定したCSSメディアクエリのタイミングで読み込まれる。例えばスマホサイズの時のみ表示したいハンバーガーメニューなどは、そのスマホサイズを指定しておくことで読み込みタイミングを調整し、PCの時などは読み込まないようにすることができる。
only
優先度: 特殊、SSR(詳細はこちらの記事)の際にサーバー側でレンダリングさせるのではなく、明示的にブラウザ側でレンダリングさせたいという場合に利用する。ブラウザ専用APIを初期化時からガッツリ使う外部ライブラリ(リッチテキストエディタ、地図描画ライブラリなど)を使う場合、サーバー側ではエラーになる可能性があるものについてはこちらを利用する。
これまで紹介したものとは違い、ブラウザのパフォーマンスに関わるというよりはエラーに対処するために使う意味合いが強い。
まとめ
Astroのアイランドアーキテクチャの根幹を担っているクライアントディレクティブについて、これまで説明した内容を表にまとめると以下のようになる。まずは5つのクライアントディレクティブがあるということ、そしてそれぞれは読み込みのタイミングが変わってくるということを理解し、自分の作成した部品の特性に合わせて使い分けすることが大事になってくる。
| 優先度 | ディレクティブ | 読み込みのタイミング | 具体的な使用例 |
|---|---|---|---|
| 高 | client:load | ページ表示時(即座) | すぐ操作するグローバルナビ、メインビジュアル |
| 中 | client:idle | ブラウザの処理が落ち着いた時 | すぐには操作されないタブ、解析スクリプト |
| 低 | client:visible | 要素が画面に表示された時 | ページ下部の重いグラフ、いいねボタン |
| 条件 | client:media | メディアクエリ一致時 | スマホ専用のハンバーガーメニュー |
| 特殊 | client:only | ブラウザ側のみ(SSRスキップ) | window APIに依存するマップやリッチエディタ |
ひとまず早く表示するに越したことはない、としてloadを使いまくっていると、初期表示に多くのことをしようとして遅くなる。あくまでバランスが大事ということを念頭に置いておこう。



