前々回のブログ で、「Astro4.0のIncremental Content Caching (Experimental)を試したけど、わずかにしか早くならなかった」と書きました。その原因は、この機能はAstro V2で導入されたコンテンツコレクション(Content Collections)に依存しているからでした。
EY-OfficeサイトはAstro V1ベースで作られていたので、コンテンツコレクション に対応し Incremental Content Caching (Experimental)を試したところ、確かに高速化されました!
コンテンツコレクション(Content Collections)への対応
コンテンツコレクションは、ブログ等のコンテンツの集まりを効率的に管理するための機能でです。
コンテンツコレクションへの対応は公式ドキュメントのファイルベースのルーティングからの移行に書かれています。
移行手順は、
- Astro V2以降にバージョンアップ
- コレクションを
src/content/
ディレクトリーに移動 - コンテンツタイプのスキーマを定義
src/content/config.ts
- コレクションの取得APIを
Astro.glob()
からgetCollection()
に変更
ブログ管理ライブラリーの変更
EY-Officeサイトのブログを管理するために、BlogPost.ts
というモジュールを書いています。機能は、一覧の取得、最新ブログ、前ブログ、次ブログの取得、カテゴリー別の取得などです。
現バージョンのBlogPost.tsの一部
- ① このモジュールが読み込まれた時点で
import.meta.glob
(Astro.glob
と同じ機能)を使い、全ブログを読み込みす- postImportResultは
{ブログパス名:ブログ内容}
のオブジェクトなので値を取り出し、並びを逆(最新を添字0)にしています - ブログ内容は
posts
配列に入ります
- postImportResultは
- ② ここに並ぶ関数は、次ブログのリンク、前ブログのリンク、最新ブログの内容、カテゴリー別ブログの内容を取得するAPIです
- これらのAPIはブログ記事ページやブログの右側のサイドバー、その他のページで使われています。
// ↓ ①
const postImportResult = import.meta.glob('../_blog/*/*.md', { eager: true });
const posts = Object.values(postImportResult).reverse() as MarkdownInstance<Record<string, any>>[];
console.log(`\n*** Blog count = ${posts.length}\n`);
// ↓ ②
export const nextPostLink = (ix: number): PostLinkType =>
ix > 0 ? {title: posts[ix - 1].frontmatter.title, path: blogUrl(posts[ix - 1])} : null;
export const previousPostLink = (ix: number): PostLinkType =>
ix < posts.length - 1 ? {title: posts[ix + 1].frontmatter.title, path: blogUrl(posts[ix + 1])} : null;
export const lastBlog = () => {
return blogInfo(posts[0]);
};
export const categoryBlogs = (category: string) => {
return posts.filter((post) => post.frontmatter.categories.includes(category)).
map(post => blogInfo(post));
}
Content Collections対応バージョンのBlogPost.tsの一部
- ① Content Collectionsからコンテンツの取得は
getCollection()
APIを使うのですが、このAPIは非同期なのでgetAllBlogs()
APIをトップページ表示のさいに呼び出してもらいposts
配列にブログを格納します - ② したがって取得APIは、変更なしです
// ↓ ①
let posts: CollectionEntry<"blog">[] = [];
export const getAllBlogs = async() => {
if (posts.length === 0) {
console.trace();
posts = await getCollection("blog");
posts.reverse();
console.log(`\n*** Blog count = ${posts.length}\n`);
}
}
// ↓ ②
export const nextPostLink = (ix: number): PostLinkType =>
ix > 0 ? {title: posts[ix - 1].frontmatter.title, path: blogUrl(posts[ix - 1])} : null;
export const previousPostLink = (ix: number): PostLinkType =>
ix < posts.length - 1 ? {title: posts[ix + 1].frontmatter.title, path: blogUrl(posts[ix + 1])} : null;
export const lastBlog = () => {
return blogInfo(posts[0]);
};
export const categoryBlogs = (category: string) => {
return posts.filter((post) => post.frontmatter.categories.includes(category)).
map(post => blogInfo(post));
}
このように小規模の変更でコンテンツコレクションに対応できました。
その他の変更
それ以外の変更点は以下です。
- MarkdownのレンダリングAPIが
.compiledContent()
からawait .render()
に変更 - RSS作成も大きく変更、RSSフィードの追加:記事の全文を含める に詳しく書かれています
高速化されたのか?
はい、早くなりました。😃
JS | Collections | Caching | ビルド時間 |
---|---|---|---|
Node.js | なし | なし | 7.9 秒 |
Bun | なし | なし | 7.4 秒 |
Node.js | あり | なし | 10.1 秒 |
Bun | あり | なし | 10.2 秒 |
Node.js | あり | あり | 6.2 秒 |
Bun | あり | あり | 6.1 秒 |
- Collections: Content Collections
- Caching: Incremental Content Caching (Experimental)
今回はBunでの高速化はありませんでしたが、Incremental Content Caching を有効にすると40%近く早くなりました。
よいお年をお迎えください
今年も毎週ブログを書けました。たまにネタが無くて苦心した事もありましたが12月はAstroさんにネタを提供して頂きたすかりました。😃
皆さま、よいお年をお迎えください。