YOSHINO日記

プログラミングに関すること

Railsのstale?: キャッシュを利用してサーバー負荷を減らす

Etag?

Browser Cache: How ETags works in Rails 3 and Rails 4 - mohanraj nagasamy f:id:taiki44no:20180820070724p:plain

Ruby on Rails のConditionalGet について

サーバは応答するときにコンテンツの Last-Modified とETag を付与します。ブラウザはその値を覚えておきます。

同じコンテンツにアクセスするとき、 ブラウザは ETag の値をIf-None-Match ヘッダとしてサーバに送信します。

サーバでは前回の ETag と同一かどうか確認し、同一であれば 304 Not Modified という応答を返します。このとき応答するのはヘッダのみでよいため、ネットワークトラフィックの節約になります。

stale?を使う理由

Request1を受けた時にサーバー側で、そのetagが最新のものかどうかを判断することができるので、

Response1、Request2の部分が不要になり、より速い応答が可能になります。

ActiveStorage:ファイルをダウンロードする時のキャッシュの利用

ActiveStorageでは、Blobを媒介してS3やGCSからファイルをダウンロードします。

Fix up DiskController and add basic testing · rails/activestorage@4712e23 · GitHub

  def show
    if key = decode_verified_key
      blob = ActiveFile::Blob.find_by!(key: key)

      if stale?(etag: blob.checksum)
        send_data blob.download, filename: blob.filename, type: blob.content_type, disposition: disposition_param
      end
    else
      head :not_head
    end
  end

上記のようにstale?メソッドを利用してetagを確認しています。

今回の例では、リクエストが新鮮(前回から変更なし:stale?がtrue)な場合は処理不要になります。

デフォルトのレンダリングでは、前回のstale?呼び出しの結果に基いて処理が必要かどうかを判断し、:not_modifiedを送信します。