mybook

第5章 — アプリケーションキャッシュ: コードで制御する

HTTP キャッシュの向こう側

「HTTP キャッシュと CDN で外側は速くなった。でも、サーバー内部の処理が遅ければ意味がない」

ケンジはマナミにアプリケーションキャッシュの世界を見せた。

フラグメントキャッシュ

ページ全体ではなく、ページの一部分(フラグメント)をキャッシュする。

Loading diagram...
<!-- Rails のフラグメントキャッシュ -->
<% cache @product do %>
  <div class="product-detail">
    <h1><%= @product.name %></h1>
    <p><%= @product.description %></p>
    <span class="price"><%= @product.price %></span>
  </div>
<% end %>
 
<% cache ["reviews", @product] do %>
  <div class="reviews">
    <%= render @product.reviews %>
  </div>
<% end %>

ロシアンドールキャッシュ

フラグメントキャッシュを入れ子にする戦略。外側のキャッシュが有効なら、内側の計算も完全にスキップされる。

Loading diagram...
<!-- 外側: 商品一覧 -->
<% cache ["product_list", @products.maximum(:updated_at)] do %>
  <% @products.each do |product| %>
    <!-- 内側: 個別の商品カード -->
    <% cache product do %>
      <div class="product-card">
        <h3><%= product.name %></h3>
        <span><%= product.price %></span>
      </div>
    <% end %>
  <% end %>
<% end %>

INFO

ロシアンドールの威力: 100商品中1商品が更新された場合、外側のキャッシュだけ無効化され、残り99商品のカードは内側のキャッシュが効く。再計算は1商品分だけ。

Memoization(メモ化)

同じメソッド呼び出しの結果をインスタンス変数に保存し、リクエスト内で再利用する。

class Product < ApplicationRecord
  def tax_included_price
    @tax_included_price ||= calculate_complex_tax(price)
  end
end
Loading diagram...

Next.js のキャッシュ戦略

Next.js は複数のキャッシュ層を内蔵している。

説明場所
Router Cacheクライアント側のルートキャッシュブラウザ
Full Route Cacheサーバーで静的レンダリング結果をキャッシュサーバー
Data Cachefetch の結果をキャッシュサーバー
Request Memoization同一リクエスト内の重複 fetch を排除サーバー
// Next.js: ISR(Incremental Static Regeneration)
export const revalidate = 60 // 60秒ごとに再検証
 
async function ProductPage({ params }) {
  const product = await fetch(`/api/products/${params.id}`, {
    next: { revalidate: 60 }
  })
  return <ProductDetail product={product} />
}

キャッシュキーの設計

アプリケーションキャッシュで最も重要なのはキャッシュキーの設計だ。

# ❌ 悪いキー: 粒度が荒い
cache_key = "products"
 
# ✅ 良いキー: 一意で、更新で変わる
cache_key = "product:#{id}:v#{updated_at.to_i}"
 
# ✅ 良いキー: 関連データの変更も反映
cache_key = "product:#{id}:reviews:#{reviews.count}"

WARNING

キャッシュキーの設計ミスは「古いデータが延々と返される」最大の原因。キーには必ずバージョン情報を含める。

マナミの実装

FreshMarket のアプリケーションキャッシュ戦略:

Loading chart...

アプリケーションキャッシュの導入で、サーバー内部の処理が平均 95% 高速化した。

次の章では、アプリケーションキャッシュの裏側を支える Redis を深掘りする。