たまには技術的な話もしよう。
本ブログ「のうらリリースノート」は CMS に Strapi、フロントエンドには Astro を利用している。このたびカテゴリ別の記事一覧ページを追加した。以下はホークスカテゴリの記事一覧ページだ。
ページ自体は作ったものの、まだどこからもリンクしていないので現状は URL を手打ちする必要がある。ここは後で実装する予定。
カテゴリページの実装にあたり、CMS からの記事取得方法を少し効率化した。
% tree src/pages
src/pages
├── category
│ └── [slug]
│ ├── index.astro
│ └── page
│ └── [page].astro
├── entry
│ └── [slug].astro
├── index.astro
└── page
└── [page].astro
6 directories, 5 files
現在の Astro のページ構成は上記のとおり。/page/[page].astro は記事一覧ページ用(例:/page/2/、/page/3/)のテンプレートで、entry/[slug].astro は記事詳細ページ(例:/entry/keiba-20251102-result/)のテンプレートだ。
今回、新たに category/[slug]/page/[page].astro を追加してカテゴリー記事一覧ページを作ったわけだが、そこで問題が一つ。「カテゴリー一覧ページで表示する内容は、もともと /page/[page].astro で取得しているものとほぼ同じ」であり、Strapi に再度アクセスする必要がなかった。
そこで、記事一覧取得が重複しないよう、Strapi から取得したデータをキャッシュして再利用する形にした。
const articlesListCache = new Map<number, Promise<Article[]>>();
export const getArticles = (pageSize: number) => {
const cached = articlesListCache.get(pageSize)
if (cached) return cached
const promise = fetchArticles(pageSize)
articlesListCache.set(pageSize, promise)
return promise
}
上のコードは論理的なイメージだ。このgetArticlesを複数のページテンプレートから呼び出している。ビルド時にどのページが最初に走るかわからないため、Promise をキャッシュする形にしている。
今はまだ記事数が多くないので、API 負荷削減やビルド時間にどれほど効いているかは実感しづらい。ただ、やらないよりは確実に良いはず。
次はカテゴリページへのリンク実装と、「全件取得 → ビルド」ではなく「一部取得 → ビルド」を繰り返す形への変更かな。