Leon . Kang
Back to articles
Performance 2/3/2026 8 min read

Blogの読み込みとレンダリング戦略(選択的分割版)

なぜ分割するのか

このブログは個人の記録サイトに過ぎませんが、それでも「クリーン、軽量、安定」であることを望んでいます。特に:

  • 初回読み込み時に不要なものを読み込まない
  • 記事閲覧ページを可能な限りスムーズに保つ
  • コードハイライトやTOC(目次)のような「必須ではない」機能は後回しにする

読み込み戦略:軽いものを先に、重いものは後に

1) ルートレベルのレイジーロード

BlogList / BlogDetailReact.lazy によって分割されています。
ユーザーが実際にBlogセクションに入った時のみ、関連コードが読み込まれます。

2) データレイヤー:リストはメタ情報のみ取得

リストページではタイトル、抜粋、カテゴリ、公開日などのメタ情報のみを必要とします。
記事の本文は、詳細ページに入った時に初めて取得されます。

また、Markdownの解析が重複しないよう、ローダーにキャッシュを追加しました。

3) 詳細ページの「選択的読み込み」

詳細ページではまず構造と記事ヘッダーをレンダリングし、本文(Markdownレンダラー)は非同期で読み込みます:

  • react-markdown/remark/rehype は遅延読み込みされます
  • コードハイライトコンポーネント react-syntax-highlighter は、コードブロックがある場合のみ読み込まれます
  • TOCの解析(extractTOC)も動的import内で実行されます

これにより、メインコンテンツがより早く届き、重いリソースは後から読み込まれるようになります。

レンダリング戦略:軽量なレンダリング、重厚な効果

Markdown レンダリング

  • コンテンツは ReactMarkdown によってレンダリングされます
  • remark-gfm によりテーブルやタスクリストをサポート
  • rehype-slug で見出しにアンカーを生成し、TOCを使いやすくします

コードブロック

コードブロックのレンダリングは、ハイライトコンポーネントの読み込みをトリガーします。
ハイライトがまだ読み込まれていない場合は、まず基本的な pre スタイルを表示し、読者を待たせないようにします。

画像

画像は統一コンポーネントで処理され、デフォルトで lazy/async 設定になっています。
これにより、本文のレンダリングが画像によってブロックされるのを防ぎます。

私が気にしているのは「速さ」ではなく「管理可能であること」

極限のパフォーマンススコアを追求しているわけではありませんが、以下のことを望んでいます:

  • 初回読み込みが管理可能であること
  • レンダリングパスが明確であること
  • 体験が突然重くならないこと

そのため、今回の最適化は単なる圧縮や高速化ではなく、一種の「秩序」に近いものです。

まとめ

この戦略の核は一言に尽きます:
「後回しにできるものは後回しにし、オンデマンドで読み込めるものはオンデマンドで読み込む」

これは個人サイトに適しており、私の好みにも合致しています。