Railsでのクライアント側のキャッシュ:条件付きGETリクエスト
ロシアの人形のキャッシュに加えて、Railsアプリのパフォーマンスを高速化するためのより多くのテクニックがあります。今回は、Railsに組み込まれている条件付きGETサポートについて説明します。これにより、レンダリングされたページをユーザーのブラウザキャッシュに保存できます。
👋キャッシング以外のパフォーマンスについてもっと知りたい場合は、Ruby(on Rails)のパフォーマンスについてもっとたくさん書いています。Rubyパフォーマンス監視チェックリストをチェックしてください。
EtagおよびLast-Modifiedヘッダー
ブラウザがRailsアプリのページに対してHTTPGETリクエストを実行すると、ルーターはそのページをコントローラーアクションの1つにリンクします。次に、コントローラーはデータベースから必要なデータを要求し、ビューをレンダリングします。 HTTP応答(200 OK
応答コードとして)は、ブラウザが解析して表示できるように、応答の本文のビューからレンダリングされたHTMLとともにブラウザに返送されます。
リソースが再度要求されると、同じパイプラインを通過します。その間にページが変更されなかったため、これが不要な場合もあります。そのために、HTTPは ETagを提供します および最終変更 ヘッダー。これらを使用すると、ブラウザは応答本文を保存し、ヘッダーを使用して、古くなったときに無効にすることができます。
Etags 、またはエンティティタグ 、はクライアント側のキャッシュ検証に使用されるため、HTTP応答のキャッシュキーと考えることができます。これらは、リクエストごとにHTTP応答ヘッダーでブラウザに返されます。
~ $ curl -I https://localhost:3000/products/1
HTTP/1.1 200 OK
...
ETag: W/"9462d76cc55aeb6249fa990e39231c7c"
Last-Modified: Wed, 25 Apr 2018 08:27:04 GMT
...
後で応答が繰り返される場合、ブラウザはキャッシュ内の既存の応答を見つけ、最後の要求から保存されたEtagをIf-None-Match
として使用します。 ヘッダ。このヘッダーは、Railsアプリにこのバージョンがすでにキャッシュにあることを通知します。
リクエストからのEtagが現在のものと一致する場合、Railsは304 Not Modified
を送信します 応答本体なしの応答。これにより、代わりにローカルキャッシュからのものを使用するようにブラウザに指示されます。
~ $ curl -i -H 'If-None-Match: W/"9462d76cc55aeb6249fa990e39231c7c"' https://localhost:3000/products/1
HTTP/1.1 304 Not Modified
...
ETag: W/"9462d76cc55aeb6249fa990e39231c7c"
Last-Modified: Wed, 25 Apr 2018 08:27:04 GMT
...
Railsでの条件付きGETリクエスト
ローカルのRailsアプリケーションからページをリクエストすると、RailsがリクエストごとにEtagを自動的に追加することがわかります。同じページを2、3回続けてリクエストすると、リクエストごとにEtagの変更を確認できます。
RailsはデフォルトでリクエストごとにEtagを生成しますが、応答本文全体のダイジェストを使用して生成します。これは、<%= csrf_meta_tags %>
を意味します レイアウトでは、リクエストごとにcsrf-tokenメタタグが変更されるため、Etagがオフになります。リクエストごとに本文が変更されるため、Etagは無効になり、ローカルキャッシュは古くなったとマークされます。
その上、Railsは304 Not Modified
を返すことはありません。 デフォルトでは、ローカルキャッシュがコントローラーで明示的にフレッシュとしてマークされることはないためです。
fresh_when
およびstale?
条件付きGETのリクエストヘッダーからEtagsを使用するには、ローカルキャッシュ内のオブジェクトを「フレッシュ」として明示的にマークする必要があります。たとえば、商品を表示するページの場合、商品とビューテンプレートが変更されない限り、キャッシュを最新の状態に保つことができます。それを機能させるために、2つのことを行います。
- Etagを構成する値を明示的に設定します。これは、応答本文全体を使用すると、キャッシュされた応答が有効かどうかを確認するために本文全体をレンダリングする必要があり、ページをローカルにキャッシュすることによるスピードアップが無効になるためです。
- リクエストヘッダーのEtagを、前に予測したEtagと比較します。 ビューをレンダリングします。一致する場合はレンダリングを省略します。
Railsには、私たちのためにすべてを行うヘルパーが付属しています。 fresh_when
を使用すると、製品に基づいてEtagと最終更新日を明示的に設定できます。 。
# app/views/products/show.html.erb
def show
@product = Product.find(params[:id])
fresh_when @product
end
明示的なrespond_to
がある場合 ブロック、stale?
を使用 fresh_when
の代わりに 。
# app/views/products/show.html.erb
def show
@product = Product.find(params[:id])
if stale?(@product)
respond_to do |format|
format.html
end
end
end
これで、製品ページの1つを要求すると、応答がローカルにキャッシュされます。同じページへの後続のリクエストには、キャッシュされた応答があることをRailsに通知するEtagが含まれ、新しいEtagと比較されます。それが一致する場合、Railsはページのレンダリングをスキップし、304 Not Modified
を返します。 すぐに。
注 :ページを更新すると、常にキャッシュされていないバージョンのページが要求されます。条件付きGETが機能するかどうかをテストするには、リンクを使用するか、代わりに戻るボタンを使用して移動します。
この記事とAppSignalAcademyシリーズの以前の記事はどうでしたか? Railsでのキャッシングに関する記事がさらにいくつか並んでいますが、次に何について書きたいか(キャッシング関連またはその他)を遠慮なくお知らせください!
-
RailsをAWSLambdaにデプロイする
サーバーレスコンピューティングは、サーバーの管理とプロビジョニングの作業をクラウドプロバイダーに任せるのに役立ち、ほとんどのテクノロジーチームにとって急速に重要になっています。 AWS Lambdaは、多くのテクノロジーチームで使用されているサーバーレステクノロジーの一種です。 AWS Lambdaは、NodeJS、Java、Python、Rubyなどのコアプログラミング言語のほとんどをサポートしています。コアプログラミング言語はサポートされていますが、これらの言語で構築されたフレームワークの一部である機能に依存してサーバーレス関数を実行したい場合があります。この投稿では、AWSLambdaで
-
Rails5でのAngularの使用
あなたは前にその話を聞いたことがあります。分散型で完全に機能するバックエンドAPIと、通常のツールセットで作成されたフロントエンドで実行されているアプリケーションがすでにあります。 次に、Angularに移動します。または、AngularをRailsプロジェクトと統合する方法を探しているだけかもしれません。これは、この方法を好むためです。私たちはあなたを責めません。 このようなアプローチを使用すると、両方の世界を活用して、たとえばRailsとAngularのどちらの機能を使用してフォーマットするかを決定できます。 構築するもの 心配する必要はありません。このチュートリアルは、この目的のた