Astroでフロントエンドフレームワークを読み込む時の注意点
今回はAstroでVueやReactといったフロントエンドフレームワーク(CSR)を読み込んで表示する際の注意点を自分なりにまとめてみました。
公式ドキュメントには一応書いてあったものの断片的、英語のみだったのでお役に立てれば嬉しいです。
CSR(クライアントサイドレンダリング)とは
CSRはサーバー上ではなくブラウザ上でJavaScriptを実行してDOMを生成し、コンテンツを画面に表示する。この時HTMLファイルは空っぽでありブラウザ側でデータを取得してからレンダリングする。
つまり初期のロードではコンテンツが何も表示されない(HTMLファイルが空)、よってSEOにはどちらかというと不向きということになります。
Astroでフロントエンドフレームワークを使う
Astroは基本的にJavaScriptの使用を抑えてHTMLとCSSだけで表現するというのが売りではありますが、APIから取ってきたデータを表示、編集したいなどといった状況に応じて部分的にJavaScriptを使うことができます。
フレームワークを読み込む際は主にこれらを使うことになると思われます。
下にドキュメントを貼っておくので他のも気になるということであれば参考にしてみてください。
---
---
<MyReactComponent client:load/>
//ページを読み込んだ際に即座に読み込む
<MyReactComponent client:idle/>
//ページの初期ロードが終わった後、requestIdleCallbackイベントが発生したら読み込む
<MyReactComponent client:visible/>
//コンポーネントがユーザーのビューポートに入ったら読み込む
<MyReactComponent client:only="react"/>
//HTMLサーバレンダリングをスキップし、クライアント上でのみレンダリング。あとはclient:loadと同じ
//only={string}のstringの部分は正しいフレームワーク名を入力すること
<MyReactComponent client:media/>
//特定のCSSメディアクエリが満たされると読み込む
この中で特に使われると予想されるのは client:load client:visible client:only="" なのかなと個人的には思います。
client:visibleは初期表示するには重い部分を目に入った時に読み込むようにできるので初期表示のスピードを上げることができます。
個人的に気になっているのは、client:loadとclient:only="" でどちらが早く表示できるかということでした。
試しにサンプルコードを書いて検証します。
---
import Fetchswr from "~/components/Fetchswr";
import Layout from "~/layouts/Layout.astro";
---
<Layout meta={{
title: 'Hello MyPage',
}}>
<main>
<h1>Astroファイル表示中</h1>
<Fetchswr client:load/>
<Fetchswr client:only="react"/>
</main>
</Layout>
import axios from 'axios'
import useSWR from 'swr'
const api_key = import.meta.env.PUBLIC_API_KEY
let date = new Date()
let todayYear = date.getFullYear()
let todayMonth = date.getMonth()+1
let todayDay = date.getDate()
const Fetchswr = () => {
let url: string = `https://api.nhk.or.jp/v2/pg/list/400/g1/${todayYear}-${todayMonth}-${todayDay}.json?key=${api_key}`
const fetcher = async () => {
const res = await axios.get(url)
return res.data.list.g1
}
const {data,isLoading} = useSWR(date,fetcher)
return (
<div>
{isLoading?<h1 className='text-amber-600'>読み込みなう</h1>:null}
{data && (
<ul>
{data.map((item: any) => {
return (
<li key={item.id}>
<p>{item.title}</p>
</li>
)
}
)}
</ul>
)}
</div>
)
}
export default Fetchswr
NHKのAPIを叩いて福岡の今日の番組一覧を表示してみます。
そうするとclient:loadでReactを読み込んだ際は一瞬だけ "読み込みなう" というオレンジ色の文字が表示されたのに対して、client:only="react"で読み込んだ際は一瞬も "読み込みなう" というオレンジ色の文字は表示されませんでした(少なくとも自分の目では認識できなかった)
また、Chromeのネットワークも確認してみたところこのコンポーネントを読み込んでいるスピードもclient:only="react"の方が速いことがわかりました。
ドキュメントを読む限りではこの二つに速さ以外で特に違いはなかったのですが、いまいち腑に落ちないので有識者の方がいらっしゃいましたらコメントしていただけると幸いです。