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