Skip Navigation
Show nav
Dev Center
  • Get Started
  • ドキュメント
  • Changelog
  • Search
  • Get Started
    • Node.js
    • Ruby on Rails
    • Ruby
    • Python
    • Java
    • PHP
    • Go
    • Scala
    • Clojure
    • .NET
  • ドキュメント
  • Changelog
  • More
    Additional Resources
    • Home
    • Elements
    • Products
    • Pricing
    • Careers
    • Help
    • Status
    • Events
    • Podcasts
    • Compliance Center
    Heroku Blog

    Heroku Blog

    Find out what's new with Heroku on our blog.

    Visit Blog
  • Log inorSign up
View categories

Categories

  • Heroku のアーキテクチャ
    • Dyno (アプリコンテナ)
      • Dyno Management
      • Dyno Concepts
      • Dyno Behavior
      • Dyno Reference
      • Dyno Troubleshooting
    • スタック (オペレーティングシステムイメージ)
    • ネットワーキングと DNS
    • プラットフォームポリシー
    • プラットフォームの原則
  • Developer Tools
    • コマンドライン
    • Heroku VS Code Extension
  • デプロイ
    • Git を使用したデプロイ
    • Docker によるデプロイ
    • デプロイ統合
  • 継続的デリバリーとインテグレーション
    • 継続的統合
  • 言語サポート
    • Node.js
      • Working with Node.js
      • Node.js Behavior in Heroku
      • Troubleshooting Node.js Apps
    • Ruby
      • Rails のサポート
      • Bundler の使用
      • Working with Ruby
      • Ruby Behavior in Heroku
      • Troubleshooting Ruby Apps
    • Python
      • Working with Python
      • Python でのバックグランドジョブ
      • Python Behavior in Heroku
      • Django の使用
    • Java
      • Java Behavior in Heroku
      • Working with Java
      • Maven の使用
      • Spring Boot の使用
      • Troubleshooting Java Apps
    • PHP
      • PHP Behavior in Heroku
      • Working with PHP
    • Go
      • Go の依存関係管理
    • Scala
    • Clojure
    • .NET
      • Working with .NET
  • データベースとデータ管理
    • Heroku Postgres
      • Postgres の基礎
      • Postgres スターターガイド
      • Postgres のパフォーマンス
      • Postgres のデータ転送と保持
      • Postgres の可用性
      • Postgres の特別なトピック
      • Migrating to Heroku Postgres
    • Heroku Data For Redis
    • Apache Kafka on Heroku
    • その他のデータストア
  • AI
    • Working with AI
    • Heroku Inference
      • Inference API
      • Quick Start Guides
      • AI Models
      • Inference Essentials
    • Vector Database
    • Model Context Protocol
  • モニタリングとメトリクス
    • ログ記録
  • アプリのパフォーマンス
  • アドオン
    • すべてのアドオン
  • 共同作業
  • セキュリティ
    • アプリのセキュリティ
    • ID と認証
      • シングルサインオン (SSO)
    • Private Space
      • インフラストラクチャネットワーキング
    • コンプライアンス
  • Heroku Enterprise
    • Enterprise Accounts
    • Enterprise Team
    • Heroku Connect (Salesforce 同期)
      • Heroku Connect の管理
      • Heroku Connect のリファレンス
      • Heroku Connect のトラブルシューティング
  • パターンとベストプラクティス
  • Heroku の拡張
    • Platform API
    • アプリの Webhook
    • Heroku Labs
    • アドオンのビルド
      • アドオン開発のタスク
      • アドオン API
      • アドオンのガイドラインと要件
    • CLI プラグインのビルド
    • 開発ビルドパック
    • Dev Center
  • アカウントと請求
  • トラブルシューティングとサポート
  • Salesforce とのインテグレーション
  • 言語サポート
  • Ruby
  • Rails のサポート
  • Rails でのキャッシング戦略

Rails でのキャッシング戦略

日本語 — Switch to English

最終更新日 2024年04月25日(木)

Table of Contents

  • HTTP キャッシング
  • ページキャッシング
  • アクションキャッシング
  • フラグメントキャッシング
  • 低レベルキャッシング
  • 参考情報

Web アプリケーションでは、ごく一部のページのロードに非常に時間がかかるのが一般的です。Heroku では、実行時間の長いリクエストによって dyno が拘束され、アプリケーションのパフォーマンスに深刻な影響が出る可能性があります。どのページやデータベースリクエストの実行速度が遅いかを確認するには、New Relic​ を使用します (Web の 「Transactions」 (トランザクション) および 「Database」 (データベース) タブを参照)。最も実行時間が長いリクエストを調べます。低速なデータベースまたは API トランザクションが原因の場合、(Rails.cache.read/write/fetch​ などの) 低レベルキャッシングを使用して情報をキャッシュします。

cache-money や cache_fu などの ‘自動的で魔法のような’ キャッシングライブラリは使用しないことをお勧めします。Heroku でも時間をかけて簡易なキャッシングソリューションを調査しましたが、満足できるものは見つかりませんでした。一般的に、キャッシングはアプリケーション固有の取り組みです。Heroku で実行する Rails アプリでキャッシングによってパフォーマンスの向上を目指すロードマップについて、以下で説明します。

memcached を使用するようにアプリケーションを設定​すると、Rails では、アクションとフラグメント両方のキャッシングに memcached を自動的に使用するようになります。

HTTP キャッシング

Rails での HTTP ヘッダーを使用したキャッシング​は、コードをほとんど変更しなくてもアプリケーションに簡単に適用できる手法であり、こちらの別記事で説明しています。

ページキャッシング

Rails の page_caching gem​ は、ファイルシステム上にファイルを作成することによって機能します。Heroku には一時的なファイルストア​があるため、ページキャッシングは一見有効そうですが、意図したようには機能しません。代わりに、アクションキャッシングまたはフラグメントキャッシングを使用してください。あるいは、Rack::Cache をリバースプロキシとして使用して、アプリへのリクエストを全面的に回避してください。

アクションキャッシング

ページで認証またはその他の事前/事後フィルターが必要な場合でも、Rails の action_caching gem​ を使用してコンテンツをキャッシュできます。アクションキャッシングは Memcache アドオン​を使用します (また、必要とします)。

特定のアクションでキャッシングを有効にするには、caches_action :<action_name>​ をコントローラーに追加するだけです。レイアウトに動的な要素が含まれる (たとえば、ユーザー名やメールアドレスがヘッダーに含まれる) 場合、アクションの内容をキャッシュしたままレイアウトを動的にレンダリングできます。これを行うには、:layout => false​ フラグを使用します。最後に、expire_action​ コマンドを使用すると、新しいデータが書き込まれたときにキャッシュからアクションを削除できます。

次の Rails コントローラーのコードは、以上の概念を示しています。

# products_controller.rb
class ProductsController < ActionController

  before_filter :authenticate
  caches_action :index
  caches_action :show, :layout => false

  def index
    @products = Product.all
  end

  def show
    @product = Product.find(params[:id])
  end

  def create
    expire_action :action => :index
  end

end

(引用元: ​Rails ガイド)

フラグメントキャッシング

フラグメントキャッシングは、アプリケーションでウィジェットまたは部品をキャッシュするための優れたメカニズムです。フラグメントキャッシングは Memcache アドオン​を使用します (また、必要とします)。たとえば、アプリで次のようにして商品を一覧表示するとします。

# index.html.erb
<%= render :partial => "product", :collection => @products %>

# _product.html.erb
<div><%= link_to product, product.name %>: <%= product.price%></div>
<div><%= do_something_comlicated%></div>

このとき、フラグメントキャッシングを使用すると、個別商品の部品を簡単にキャッシュできます。ActiveRecord オブジェクトを Rails に渡すと、Rails によってキャッシュキーが自動的に生成されます。

# _product.html.erb
<% cache(product) do %>
   <div><%= link_to product, product.name %>: <%= product.price%></div>
   <div><%= do_something_comlicated%></div>
<% end %>

もう 1 つのフラグメントキャッシング戦略は、新しいページロードのたびにページのウィジェットやその他の独立部品をライブデータストアから更新する必要がない場合に、それらの要素をキャッシュするというものです。たとえば、最も売れている商品のリストを Web サイトのフロントページに表示する場合に、この部品をキャッシュすることができます。1 時間おきに情報を更新する場合、次のようになります。

# index.html.erb
<% cache("top_products", :expires_in => 1.hour) do %>
  <div id="topSellingProducts">
    <% @recent_product = Product.order("units_sold DESC").limit(20) %>
    <%= render :partial => "product", :collection => @recent_products %>
  </div>
<% end %>

低レベルキャッシング

低レベルキャッシングでは、Rails.cache​ オブジェクトを直接使用して任意の情報をキャッシュします。取得のコストが高く、多少古くなっても問題が少ないデータの保存に使用します。データベースクエリや API 呼び出しが一般的な用途です。

低レベルキャッシングは、Rails.cache.fetch​ メソッドを使用すると最も効率的に実装できます。このメソッドは、キャッシュが利用可能であればキャッシュから値を読み取り、利用できない場合は、メソッドに渡されたブロックを実行して結果を返します。

>> Rails.cache.fetch('answer')
==> "nil"
>> Rails.cache.fetch('answer') {1 + 1}
==> 2
Rails.cache.fetch('answer')
==> 2

次の例を考えてみましょう。アプリケーションの Product モデルには、すべての在庫切れ商品を返すクラスメソッドと、競合 Web サイトでの商品価格を検索するインスタンスメソッドがあります。これらのメソッドによって返されるデータは、低レベルキャッシングに最も適しています。

# product.rb

def Product.out_of_stock
  Rails.cache.fetch("out_of_stock_products", :expires_in => 5.minutes) do
    Product.all.joins(:inventory).conditions.where("inventory.quantity = 0")
  end
end

def competing_price
  Rails.cache.fetch("/product/#{id}-#{updated_at}/comp_price", :expires_in => 12.hours) do
    Competitor::API.find_price(id)
  end
end

この最後の例では、モデルの id 属性と update_at 属性に基づいてキャッシュキーを生成しています。これは一般的な方法であり、商品が更新されるたびにキャッシュが無効化されるという利点があります。一般的には、インスタンスレベルの情報に低レベルキャッシングを使用するときは、キャッシュキーを生成する必要があります。

参考情報

  • Rails でのキャッシング​ に関する RailsGuides の記事

関連カテゴリー

  • Rails のサポート
Unicorn を使用した Rails アプリケーションのデプロイ Rails データベース接続の動作

Information & Support

  • Getting Started
  • Documentation
  • Changelog
  • Compliance Center
  • Training & Education
  • Blog
  • Support Channels
  • Status

Language Reference

  • Node.js
  • Ruby
  • Java
  • PHP
  • Python
  • Go
  • Scala
  • Clojure
  • .NET

Other Resources

  • Careers
  • Elements
  • Products
  • Pricing
  • RSS
    • Dev Center Articles
    • Dev Center Changelog
    • Heroku Blog
    • Heroku News Blog
    • Heroku Engineering Blog
  • Twitter
    • Dev Center Articles
    • Dev Center Changelog
    • Heroku
    • Heroku Status
  • Github
  • LinkedIn
  • © 2025 Salesforce, Inc. All rights reserved. Various trademarks held by their respective owners. Salesforce Tower, 415 Mission Street, 3rd Floor, San Francisco, CA 94105, United States
  • heroku.com
  • Legal
  • Terms of Service
  • Privacy Information
  • Responsible Disclosure
  • Trust
  • Contact
  • Cookie Preferences
  • Your Privacy Choices