{
  "title": "爆速な技術ブログを作るために意識していること",
  "description": "Astroで静的な技術ブログを作るときに意識した、HTML、JavaScript、CSS、画像、フォント、依存関係、Lighthouse計測の見方をまとめる。",
  "locale": "ja",
  "slug": "tech-blog-performance-notes",
  "url": "https://engineer-blog.tomoki-ttttt.workers.dev/articles/tech-blog-performance-notes/",
  "publishedAt": "2026-05-16T15:00:00.000Z",
  "tags": [
    "Astro",
    "Web Performance",
    "Lighthouse",
    "技術ブログ"
  ],
  "projectIds": [
    "tech-blog"
  ],
  "markdown": "## はじめに\n\nこのブログでは、できるだけ軽く、速く、読みやすい技術ブログを目指している。\n\nこの記事では、爆速な技術ブログを作るために、実装面で意識していることをまとめる。\n\n具体的には、次のような内容を扱う。\n\n- 記事本文を静的HTMLとして出すこと\n- JavaScriptを初回表示に関与させすぎないこと\n- CSSをクリティカルパスとして見ること\n- 画像、アイコン、OGPを軽く扱うこと\n- 日本語Webフォントを安易に読み込まないこと\n- 依存関係を増やしすぎないこと\n- Lighthouseの実測値をどう見るか\n- デスクトップとモバイルを分けて確認すること\n- 爆速ブログを保つためのチェックリスト\n\nこの記事は、フレームワーク選定の話というより、実際に技術ブログを軽く保つための実装メモに近い。\n\nAstroで静的に出力しているブログを前提にしているが、Next.jsやViteなど、他の構成でブログやドキュメントサイトを作るときにも応用できる内容だと思う。\n\n## 記事本文を静的HTMLとして出す\n\n技術ブログで一番大事なのは、本文がすぐ読めることだ。\n\nそのため、このブログでは記事本文をクライアント側で組み立てるのではなく、ビルド時に静的なHTMLとして生成する方針にしている。\n\nMarkdownで書いた記事を、ビルド時にHTMLへ変換しておく。  \nブラウザは受け取ったHTMLをそのまま解釈できる。  \nJavaScriptの実行を待たなくても、本文を表示できる。\n\nこの形にしておくと、初回表示がかなり素直になる。\n\n特に避けたいのは、記事本文の表示にJavaScriptを絡めすぎることだ。\n\nたとえば、次のような構成にすると、ブログとしては必要以上に複雑になりやすい。\n\n- 記事データをクライアント側でfetchする\n- JavaScriptでMarkdownをパースする\n- Reactなどで記事本文全体を描画する\n- 初回表示時に状態管理やルーティング処理が必要になる\n\nWebアプリならそれが必要な場面もある。\n\nでも、技術ブログの記事ページは基本的に「読む」ためのページだ。  \nであれば、最初からHTMLとして置いておくのが一番速く、壊れにくいと思っている。\n\n## HTMLを膨らませすぎない\n\n静的HTMLにすればそれだけで完璧、というわけではない。\n\nHTML自体が大きくなりすぎると、それはそれで初回表示に影響する。\n\n技術ブログでは、記事本文、コードブロック、OGPメタ、構造化データ、多言語用のalternateリンクなど、意外とHTMLが膨らみやすい。\n\nなので、HTMLでは次のような点を意識している。\n\n- 不要なラッパー要素を増やさない\n- 全ページ共通のコンポーネントを重くしない\n- head内のメタタグを必要十分にする\n- OGPやSEO用の情報を過剰に入れない\n- 記事本文のHTMLサイズが不自然に大きくなっていないか確認する\n\n特に、共通レイアウトは注意が必要だ。\n\nヘッダー、フッター、SEOコンポーネント、テーマ初期化、ナビゲーションなどは全ページに乗る。  \nここが重くなると、すべての記事ページが重くなる。\n\nページ単体の実装だけでなく、共通レイアウトに何を入れているかを見るのが大事だ。\n\n## JavaScriptを初回表示に関与させない\n\nパフォーマンスを考えるうえで、JavaScriptはかなり慎重に扱っている。\n\nJavaScriptはファイルサイズだけでなく、パース、コンパイル、実行、メインスレッドの占有まで含めてコストになる。\n\n技術ブログでは、見た目上は小さな機能でも、積み重なるとかなり効いてくる。\n\nたとえば、次のような機能だ。\n\n- テーマ切り替え\n- コードブロックのコピーボタン\n- 目次の追従\n- サイト内検索\n- コメント欄\n- アニメーション\n- アクセス解析\n- 外部ウィジェット\n- シンタックスハイライト\n\nこれらは便利だが、全部を常設すると、記事を読むだけのページとしては重くなりがちだ。\n\nなので、JavaScriptを入れるときは次のように考えている。\n\n- そのJavaScriptは初回表示に本当に必要か\n- HTMLとCSSだけで実現できないか\n- 全ページで読み込む必要があるか\n- その機能がなくても記事本文は読めるか\n- メインスレッドをブロックしていないか\n- 後から消しやすい実装になっているか\n\n特に Astro の場合、必要なところだけクライアント側で動かすことができる。\n\nただし、アイランドアーキテクチャが便利だからといって、記事ページにどんどんインタラクティブなコンポーネントを足すと、結局普通の重いフロントエンドに近づいてしまう。\n\nこのブログでは、記事本文の表示にはJavaScriptを関与させないことを基本にしている。\n\nテーマ初期化のように必要な処理はあるが、それもできるだけ小さく、早く終わるようにする。\n\n## CSSをクリティカルパスとして見る\n\nCSSは見た目を整えるだけのものではなく、初回描画に直接関わる。\n\nCSSはレンダリングをブロックすることがある。  \nつまり、CSSが大きかったり、読み込みが遅かったりすると、HTMLが届いていても画面に描画されるまで待たされることがある。\n\nこのブログでは、CSSについて次のような点を意識している。\n\n- 共通CSSを肥大化させない\n- 記事ページに不要なトップページ用CSSを持ち込まない\n- 複雑なレイアウトを避ける\n- 重い装飾を多用しない\n- アニメーションやtransitionを雑に全体適用しない\n- モバイルでスクロールが重くならないようにする\n\n特に注意したいのは、見た目のための重いCSSだ。\n\nたとえば、次のようなものは使いすぎると負荷になりやすい。\n\n- `box-shadow`\n- `filter`\n- `backdrop-filter`\n- `blur`\n- 大きなグラデーション\n- 複雑なsticky要素\n- 大量のtransition\n- スクロール連動アニメーション\n\nもちろん、これらを一切使わないという話ではない。\n\nただ、技術ブログでは本文を読むことが中心なので、装飾のためにスクロールや描画を重くするのは避けたい。\n\nまた、Astro側ではCSSの出力方法も見ている。  \n小さなCSSであればインライン化した方がリクエストを減らせることがあるが、CSSが大きくなると逆効果になる場合もある。\n\nなので、CSSは「ファイルサイズ」だけでなく、レンダリングの邪魔をしていないかという視点で見ている。\n\n## 画像・アイコン・OGPを軽くする\n\n技術ブログでは、画像を使いすぎないことも重要だ。\n\n旅行ブログやメディアサイトなら画像が主役になることもあるが、技術ブログの主役は基本的に本文だ。\n\n画像が必要な場面はある。  \nスクリーンショットがあった方が分かりやすい記事もある。  \nOGP画像やアイコンも必要だ。\n\nただ、画像は簡単にページを重くする。\n\n意識しているのは次のようなことだ。\n\n- 不要なアイキャッチ画像を入れない\n- 記事と関係ない装飾画像を増やさない\n- スクリーンショットは必要な範囲だけ切り抜く\n- WebPやAVIFなど軽い形式を検討する\n- 画像のwidth / heightを指定してCLSを防ぐ\n- preloadする画像を増やしすぎない\n- OGP画像を過剰に巨大化させない\n\n特に `preload` は便利だが、使いすぎると逆に他の重要なリソースを邪魔する可能性がある。\n\n「早く読ませたいもの」を優先するための指定なので、何でも先読みすれば良いわけではない。\n\n技術ブログの場合、最優先は本文だ。\n\n画像を速く見せることより、本文が早く読めることを優先したい。\n\n## フォントはシステムフォントを基本にする\n\n日本語サイトでWebフォントを使うと、見た目は整いやすくなる。\n\nただし、日本語フォントはファイルサイズが大きくなりやすく、読み込みコストも無視できない。\n\n技術ブログでは、ブランド表現よりも本文の読みやすさと表示速度を優先したい。\n\nそのため、このブログでは基本的にシステムフォントを使う方針にしている。\n\nシステムフォントを使うメリットはシンプルだ。\n\n- 追加のフォントリクエストが不要\n- 表示が速い\n- OSに馴染んだ見た目になる\n- フォント読み込みによるちらつきが少ない\n- レイアウト変化を抑えやすい\n\nもちろん、Webフォントが悪いわけではない。\n\nブランドサイトやポートフォリオでは、フォントの印象が重要になることもある。\n\nただ、個人の技術ブログでは、まず読めること、速いこと、長く運用しやすいことを優先している。\n\n## 依存関係を増やさない\n\n高速化でかなり効くのが、依存関係を増やさないことだ。\n\nライブラリを1つ追加すると、それ自体のサイズだけでなく、関連する依存、ビルド設定、更新対応、セキュリティ対応も増える。\n\n特にクライアント側に入るライブラリは慎重に見ている。\n\nたとえば、次のようなものは便利だが、導入前に本当に必要か考える。\n\n- 日付整形ライブラリ\n- アニメーションライブラリ\n- UIコンポーネントライブラリ\n- 検索ライブラリ\n- シンタックスハイライト\n- Markdown拡張\n- 画像ギャラリー\n- コメントシステム\n\n技術ブログでは、簡単な日付表示やタグ表示くらいなら自前で十分なことも多い。\n\n検索機能やシンタックスハイライトも、記事数が少ない段階では必須とは限らない。  \n入れるとしても、全ページの初回表示に影響しない形にしたい。\n\n依存関係を増やさないことは、速度だけでなく保守性にも効く。\n\n軽いサイトを作るというより、重くなる入口を減らす感覚に近い。\n\n## 静的アセットとして配信する\n\nこのブログでは、ビルドした静的ファイルを配信する構成にしている。\n\n静的配信の良いところは、リクエスト時にアプリケーションサーバーでHTMLを生成しなくていいことだ。\n\nDBアクセスも不要。  \nAPI呼び出しも不要。  \nユーザーごとの動的生成も不要。\n\nビルド済みのHTML、CSS、JavaScript、画像をそのまま返せばいい。\n\nこの構成は、個人技術ブログとかなり相性が良い。\n\n- 構成が単純\n- 壊れにくい\n- キャッシュしやすい\n- 運用コストが低い\n- セキュリティリスクを小さくしやすい\n- サーバー側の処理時間に左右されにくい\n\nWebアプリなら動的な仕組みが必要だ。\n\nでも、記事を読むためのブログであれば、できるだけ静的に寄せた方が速く、運用も楽になる。\n\n## Lighthouseの実測値を見る\n\n高速化を考えるとき、Lighthouseはかなり便利だ。\n\nただし、Lighthouseの点数だけを見るのではなく、それぞれの指標を分けて見るようにしている。\n\nこのブログで測ったときの例は、だいたい次のような感じだった。\n\n| 環境 | FCP | LCP | TBT | CLS | Speed Index |\n|---|---:|---:|---:|---:|---:|\n| Mobile 例1 | 0.8s | 0.9s | 0ms | 0 | 0.8s |\n| Desktop 例1 | 0.4s | 0.4s | 0ms | 0 | 0.5s |\n| Mobile 例2 | 0.9s | 0.9s | 0ms | 0.001 | 2.2s |\n| Desktop 例2 | 0.3s | 0.3s | 10ms | 0.001 | 0.3s |\n\nFCP、LCP、TBT、CLSはかなり良い値が出ている。\n\n一方で、MobileのSpeed Indexだけが大きくブレることがあった。\n\nここが面白いところで、LCPが速いからといって、必ずしも画面全体の見え方が常に同じように速いとは限らない。\n\nLighthouseは一つの計測結果なので、実行するたびに多少ブレる。  \nネットワーク状態、CPU、レンダリングタイミング、画像、CSS、外部要因などによって変わる。\n\nなので、一回の結果だけで判断するのではなく、複数回測って傾向を見るようにしている。\n\n## 静的な技術ブログで狙いたい目標ライン\n\nこれはあくまで個人的な目安だが、静的な技術ブログなら、かなり攻めた数値を狙えると思っている。\n\nChatGPTと相談しながら、静的な技術ブログ向けの理論値・目標値・許容ラインを整理すると、だいたい次のようになる。\n\n| 指標 | 理論値 | 現実的な目標 | 許容ライン |\n|---|---:|---:|---:|\n| FCP | 0.2〜0.5s | 0.5〜1.0s | 1.5s未満 |\n| LCP | 0.3〜0.8s | 0.8〜1.5s | 2.0s未満 |\n| TBT | 0ms | 0〜50ms | 100ms未満 |\n| CLS | 0 | 0〜0.01 | 0.05未満 |\n| Speed Index | 0.3〜0.8s | 0.8〜1.5s | 2.5s未満 |\n\nただし、これはかなり軽いサイト前提だ。\n\nたとえば、次のようなサイトではこの目標は厳しすぎると思う。\n\n- 広告が多いメディアサイト\n- 画像が主役の旅行ブログ\n- ECサイト\n- ダッシュボード\n- ログイン後のWebアプリ\n- 外部スクリプトが多いサイト\n- 大量のWebフォントを使うサイト\n\nこのブログのように、Astroで静的HTMLを生成し、画像やJavaScriptをかなり抑えた技術ブログだからこそ、このくらいの数値を目指せるという感覚だ。\n\n## デスクトップとモバイルは別物として見る\n\nデスクトップで速いからといって、モバイルでも速いとは限らない。\n\nこれは実際に測っていてかなり感じた。\n\nデスクトップではFCPやLCPが0.3〜0.4秒台で出ることがある。  \n一方で、モバイルでは同じページでもSpeed Indexが2秒台になることがあった。\n\n理由はいろいろ考えられる。\n\n- CPU性能が違う\n- ネットワーク条件が違う\n- 画面サイズが違う\n- CSSの適用タイミングが違う\n- フォント描画の影響が違う\n- 画像の扱いが違う\n- モバイルのLighthouse条件が厳しい\n\n特に個人開発では、開発中の確認をPCで済ませがちだ。\n\nでも、実際に読む人はスマホで見ているかもしれない。\n\nだから、デスクトップだけ見て「爆速」と判断しないようにしている。\n\n最低でも、LighthouseのMobileとDesktopは両方見る。  \nできれば、実機やDevToolsのPerformanceも見る。\n\nこのくらいは習慣にしておきたい。\n\n## 数字だけに最適化しない\n\nLighthouseは便利だが、Lighthouseの数字だけに最適化しすぎるのは少し危険だと思っている。\n\n最初は、FCP、LCP、TBT、CLS、Speed Indexの数値をかなり重視していた。\n\nもちろん、これらは初回表示の状態を把握するうえで重要だ。  \n特に、静的な技術ブログでは悪い数値が出たときに原因を追いやすいので、Lighthouseはかなり役に立つ。\n\nただ、サイトの体験は一つのスコアだけでは判断できない。\n\nたとえば、LCPが良くても、スクロールが重いことはある。  \nTBTが低くても、モバイルでの表示が安定しないことはある。  \nDesktopではきれいな数値が出ていても、MobileではSpeed Indexが大きくブレることもある。\n\nだから、Lighthouseを見るときは合計スコアだけでなく、次のような観点も合わせて確認するようにしている。\n\n- FCP、LCP、TBT、CLS、Speed Indexを個別に見る\n- MobileとDesktopを分けて見る\n- 一回の計測結果だけで判断しない\n- Networkでリクエスト数と転送サイズを見る\n- Coverageで未使用のCSSやJavaScriptを見る\n- Performanceでメインスレッドの詰まりを見る\n- 実際にスクロールして重くないか確認する\n\nLighthouseは、問題を見つけるための道具としてはとても優秀だ。\n\nただ、最終的な目的はスコアを上げることではなく、読者がストレスなく記事を読める状態にすることだ。\n\n数字は見る。  \nでも、数字だけで判断しない。\n\nこのバランスを忘れないようにしたい。\n\n## 爆速技術ブログのためのチェックリスト\n\n最後に、技術ブログを軽く保つためのチェックリストをまとめる。\n\n### HTML\n\n- [ ] 記事本文はビルド時にHTML化している\n- [ ] 記事本文をクライアント側JavaScriptで生成していない\n- [ ] 不要なラッパー要素を増やしていない\n- [ ] 共通レイアウトが重くなっていない\n- [ ] head内のメタタグが過剰になっていない\n- [ ] OGP、canonical、hreflangなどは必要十分にしている\n- [ ] HTMLサイズが不自然に大きくなっていない\n\n### JavaScript\n\n- [ ] 初回表示に不要なJavaScriptを読み込んでいない\n- [ ] 記事ページにReactなどのハイドレーションを安易に入れていない\n- [ ] 記事本文の表示にJavaScriptが必須になっていない\n- [ ] テーマ初期化など必要な処理は小さく保っている\n- [ ] 外部スクリプトを増やしていない\n- [ ] コピー機能、検索、目次追従などを入れる前にコストを考えている\n- [ ] DevToolsでメインスレッドを長時間ブロックしていないか確認している\n\n### CSS\n\n- [ ] 共通CSSが肥大化していない\n- [ ] 記事ページに不要なトップページ用CSSを持ち込んでいない\n- [ ] CSSがレンダリングをブロックすることを意識している\n- [ ] `box-shadow`、`filter`、`backdrop-filter`、`blur` を多用していない\n- [ ] アニメーションやtransitionを全要素に雑に適用していない\n- [ ] sticky要素や重い装飾でスクロールが重くなっていない\n- [ ] モバイルでスクロールが重くなっていない\n\n### 画像・アイコン\n\n- [ ] 不要なアイキャッチ画像を入れていない\n- [ ] 画像はWebPやAVIFなど軽い形式を検討している\n- [ ] 画像のwidth / heightを指定している\n- [ ] スクリーンショットは必要な範囲だけにしている\n- [ ] preloadする画像を増やしすぎていない\n- [ ] favicon、アイコン、OGP画像を過剰に増やしていない\n- [ ] 画像が本文表示より優先されすぎていない\n\n### フォント\n\n- [ ] 日本語Webフォントを安易に読み込んでいない\n- [ ] システムフォントで十分か検討している\n- [ ] フォント読み込みによる表示遅延を確認している\n- [ ] フォント差し替えによるレイアウト変化を確認している\n\n### 依存関係\n\n- [ ] 便利ライブラリを追加する前に本当に必要か考えている\n- [ ] クライアント側bundleに入る依存を特に慎重に見ている\n- [ ] 日付整形やタグ表示など、軽い処理をライブラリに頼りすぎていない\n- [ ] 検索機能を入れる場合、indexサイズやJSサイズを確認している\n- [ ] シンタックスハイライトを入れる場合、全ページに余計な負荷をかけていない\n- [ ] 使っていない依存関係を残していない\n\n### 配信・ビルド\n\n- [ ] 静的ファイルとして配信できる構成になっている\n- [ ] DBやAPIを初回表示に絡めていない\n- [ ] ビルド済みのHTML/CSS/JS/画像をそのまま配信している\n- [ ] キャッシュしやすいファイル構成になっている\n- [ ] デプロイ後の成果物サイズを確認している\n- [ ] CIでbuild、lint、typecheckを確認している\n\n### 計測\n\n- [ ] LighthouseのMobileとDesktopを両方見る\n- [ ] FCP、LCP、TBT、CLS、Speed Indexを個別に見る\n- [ ] 一回の計測結果だけで判断していない\n- [ ] Networkでリクエスト数とサイズを見る\n- [ ] Coverageで未使用CSS/JSを見る\n- [ ] Performanceでメインスレッドの詰まりを見る\n- [ ] 実機またはモバイル相当環境でスクロールの重さを見る\n- [ ] デスクトップだけ速くなって満足していない\n- [ ] Lighthouseの数字だけで体験を判断していない\n\n## おわりに\n\n爆速な技術ブログを作るために必要なのは、魔法の設定を一つ入れることではなく、小さな負荷を増やさないことの積み重ねだと思っている。\n\n静的HTMLとして本文を出す。  \nJavaScriptを初回表示に関与させすぎない。  \nCSSをクリティカルパスとして見る。  \n画像やフォントを慎重に扱う。  \n依存関係を増やしすぎない。  \nデスクトップとモバイルを分けて計測する。\n\nこうした地味な判断の積み重ねが、結果として速く、軽く、長く運用しやすいブログにつながる。\n\nただし、Lighthouseの数字だけを追えばいいわけではない。\n\n初回表示が速くても、ページ遷移が遅く感じることはある。  \nデスクトップで速くても、モバイルで遅くなることもある。  \n一つのスコアだけでは、サイト全体の体験は判断できない。\n\nだからこそ、数字は見つつも、最後は実際の体感も確認する。\n\nこのバランスを忘れずに、今後もこのブログを軽く保っていきたい。\n\n---\n\n**追記（2026-05-21）：** その後、このブログに Shiki を使ってシンタックスハイライトを導入した。「軽さを崩さない形で入れること」を判断基準にした経緯については、[爆速技術ブログに Shiki でシンタックスハイライトを入れた理由](/articles/add-shiki-syntax-highlight/)にまとめている。"
}
