トップ/記事一覧
ブログのビルド時間を短縮した(Notion Blog)
📆2022/10/27🔖 Notion BlogNotion API
このブログのビルド時間を短縮した。
このブログの記事が300を超えて、GitHub Actions 上でビルドを回すと1時間ビルドに時間がかかってしまっていた。課題感は感じていたものの、うまい回避策が見つからず「まあ CI 上でバッチで回してるし別にいいか〜」と放置していたのだが、@otoyo0122 さんが開発されている easy-notion-blog のビルドがキャッシュを効かせてうまいことやっているということで、着想を得て自分もキャッシュの機構を実装。60分から10分まで縮めることができた。ありがたい。
そもそも何に時間がかかっていたか
記事ごとに、
という処理を走らせていた(全件 Fetch は Notion API の仕様上仕方なくやっている)Notion にはデータ取得数の上限があるため、50件ずつ取得しては、Rate Limit に引っかからないように 400 [ms] の待機時間を設けて再度 Fetch ということをしており、これが 300 記事分回ると時間がかかるというわけだ。
easy-notion-blog でのビルドパフォーマンス最適化
easy-notion-blog のコードリーディングをしてみると、では記事の一覧 Fetch の結果をキャッシュして、初回は Notion API からの返却値を返し、2回目以降はキャッシュを返すという実装をしていた。キャッシュはビルドごとにリセットされる仕組みになっていた。
https://zenn.dev/otoyo/articles/38e4092927f7c1
仕組みを理解し、自分のブログに取り込んだ。
実装
以下のような実装をした。easy-notion-blog ではビルド用のスクリプトを別で準備し、ビルド前に走らせていたが、自分の場合はプロダクションコードに組み込むことにした。1記事目のビルドのときは Notion API を叩いて記事データを全件取得し、キャッシュデータを作成、それ以降はキャッシュを返すようにした。
JavaScript
import { getNotionDataList } from '../lib/getNotionData' import path from 'path' import fs from 'fs' // キャッシュするファイル名 const CACHE_FILE_NAME = 'article-list-cache.json' // キャッシュデータのパス const ARTICLE_LIST_CACHE_DATA = path.resolve(CACHE_FILE_NAME) // データベース ID const DATABASE_ID = process.env.NOTION_DATABASE_ID /** * 記事一覧を取得する * キャッシュがある場合は、キャッシュを返却する(プロダクションビルド時のパフォーマンス最適化のため) */ export const getArticleList = async (): Promise<TODO[]> => { // キャッシュが存在するかどうかを判定 if (fs.existsSync(ARTICLE_LIST_CACHE_DATA)) { console.log('💥 Cache hit!') return JSON.parse(fs.readFileSync(CACHE_FILE_NAME, 'utf-8')) } // キャッシュがない場合は Notion からデータ Fetch する const database: TODO[] = await getNotionDataList(DATABASE_ID) // キャッシュファイルの書き込み fs.writeFile(CACHE_FILE_NAME, JSON.stringify(database), (err) => { if (err) throw err console.log(`✅ キャッシュファイルの書き込みが完了しました`) }) return database }
詳しくは下記の PR にて。
https://github.com/35d/35d-blog/pull/14
🐈
実装は少し別の形になったが、着想を頂いたことに感謝。自分にはなかったアイデアだったので参考になりまくりだった。ありがとうございました。他の人のコードを読むと勉強になる。
(最近また自作ブログブームが自分の中で到来している。いろいろ改善していきたい)