viphat / til

Today I Learned
http://notes.viphat.work
0 stars 1 forks source link

[PluralSight] - Rails 4.1 Performance Fundamentals - Module 4 - Browser Caching #253

Open viphat opened 6 years ago

viphat commented 6 years ago

Browser Caching

Apply for GET request only

Response: Last-modified (When the resource was last changed) Request: If-modified-since (Is the resource newer than the last time I saw it?)

Pros

Reduces response bandwidth You control when the browser uses its cache Reduces Server Load (but not automatically)

Cons

Browser sends a request every time

ETag / If-None-Match

Like Last-modified + If-modified-since - Instead of checking if the content is newer, it checks if the content is different

Response includes ETag Subsequent request includes If-None-Match (Is the resource different than the last time I saw it?)

Return HTTP Code 304-Not-Modified

Cache-Control

You’re basically telling the browser “Don’t even bother checking for a new version of this resource.” for some amount of time. (Using max-age, it will hit server until then)

Pros:

Doesn’t even hit the server when cache is still fresh.

Cons:

Browser may show out-of-date content

You can’t usually know when the resource will change in advance but what you can do is you can decide ‘I’m okay with letting users see stale data for a certain amount of time.’ if the trade-off is faster performance for users and lower load on the server,

How to use ETag in Rails

Rack::ETag and Rack::ConditionalGet are a wonderful pair of rack middleware.

stales? and fresh_when

stales?
def show
  @student = Student.find(params[:id])
  if stale?(last_modified: @student.updated_at, etag: @student)
    respond_to do |wants|
       # rnder different formats
     end
  end
end
fresh_when
def show
  @student = Student.find(params[:id])
  fresh_when last_modified: @student.updated_at,
                      etag: @student
end
Using stale? and fresh_when when in new and edit
def new
  @student = Student.new
  fresh_when last_modified: @student.updated_at,
    etag: [@student, form_authenticity_token]
end

def edit
  @student = Student.find(params[:id])
  fresh_when last_modified: @student.updated_at,
    etag: [@student, form_authenticity_token]
end
Using stale? and fresh_when with Pagination
def index
  @students = Student.order(:name).page(params[:page])
  count = Student.count
  max_updated_at = Student.maximum(:updated_at).try(:utc).try(:to_s, :number)
  fresh_when etag: "students/all-#{count}-#{max_updated_at}"
end
Propagate updated_at to Owning Objects
class Enrollment < ActiveRecord::Base
  belongs_to :course, touch: true
  belongs_to :student, touch: true 
end