March 4, 2016
This blog is part of our Rails 5 series.
Rails 5 allows to
cache HTTP responses forever by
introducing http_cache_forever
method.
Sometimes, we have static pages that never/rarely change.
# app/controllers/home_controller.rb
class HomeController < ApplicationController
def index
render
end
end
# app/views/home/index.html.erb
<h1>Welcome</h1>
Let's see log for the above action.
Processing by HomeController#index as HTML
Rendered home/index.html.erb within layouts/application (1.3ms)
Completed 200 OK in 224ms (Views: 212.4ms | ActiveRecord: 0.0ms)
And so on for every request for this action.
There is no change in the response and still we are rendering same thing again and again and again.
When response does not change then we want browsers and proxies to cache it for a long time.
Method http_cache_forever
allows us to set response headers to tell browsers
and proxies that response has not modified.
# app/controllers/home_controller.rb
class HomeController < ApplicationController
def index
http_cache_forever(public: true) {}
end
end
# OR
class HomeController < ApplicationController
def index
http_cache_forever(public: true) do
render
end
end
end
# app/views/home/index.html.erb
<h1>Welcome</h1>
Now let's look at the log for the modified code.
# When request is made for the first time.
Processing by HomeController#index as HTML
Rendered home/index.html.erb within layouts/application (1.3ms)
Completed 200 OK in 224ms (Views: 212.4ms | ActiveRecord: 0.0ms)
# For consecutive requests for the same page
Processing by HomeController#index as HTML
Completed 304 Not Modified in 2ms (ActiveRecord: 0.0ms)
On first hit, we serve the request normally but, then on each subsequent request cache is revalidated and a "304 Not Modified" response is sent to the browser.
By default, HTTP responses are cached only on the user's web browser. To allow
proxies to cache the response, we can set public to true
to indicate that they
can serve the cached response.
By using this method, Cache-Control: max-age=3155760000
is set as response
header and browser/proxy won't revalidate the resource back to the server unless
force reload is done.
In case force reload is done, Cache-Control: max-age=0
is set as request
header.
In this case, browser will receive the changed resource whether ETag is changed or not.
http_cache_forever
is literally going to set the headers to cache it for 100
years and developers would have to take extra steps to revalidate it. So, this
should be used with extra care.
If this blog was helpful, check out our full blog archive.