166
When to tell your kids about presentation caching Matthew Deiters www.theAgileDeveloper.com

When to tell your kids about Client Caching

Embed Size (px)

DESCRIPTION

RailsConf 2009 Presentation by Matthew Deiters

Citation preview

Page 1: When to tell your kids about Client Caching

When to tell your kids about presentation

caching

Matthew Deiterswww.theAgileDeveloper.com

Page 2: When to tell your kids about Client Caching

A practical guide to stuffing your app’s bits

into someone else’s browser

Page 3: When to tell your kids about Client Caching

Questions: @mdeiters

Page 4: When to tell your kids about Client Caching
Page 5: When to tell your kids about Client Caching

Rapid Feature Development

Page 6: When to tell your kids about Client Caching

Rapid Feature Development

Adoption & Growth

Page 7: When to tell your kids about Client Caching
Page 8: When to tell your kids about Client Caching

Client Caching

Page 9: When to tell your kids about Client Caching

client.is_a?(Browser) == true

Page 10: When to tell your kids about Client Caching

Browsers &Leveraging HTTP 1.1

Page 11: When to tell your kids about Client Caching

Fewer Requests

Smaller Responses

Page 12: When to tell your kids about Client Caching

80/20 Rule(Pareto Principle)

Page 13: When to tell your kids about Client Caching

80% of the wealth owned by 20% of people

Page 14: When to tell your kids about Client Caching

80% of your time is with 20% of your acquaintances

Page 15: When to tell your kids about Client Caching

80% of the time you wear 20% of your clothing

Page 16: When to tell your kids about Client Caching

80% of a request is spent on the wire

Page 17: When to tell your kids about Client Caching

Today

Page 18: When to tell your kids about Client Caching

Last-Modified Header

ETag Header

max-age Header

Expires Header

Reducing Network Traffic

GZip

Minification

Cookies

Today

Page 19: When to tell your kids about Client Caching
Page 20: When to tell your kids about Client Caching
Page 21: When to tell your kids about Client Caching

ME

Page 22: When to tell your kids about Client Caching
Page 23: When to tell your kids about Client Caching
Page 24: When to tell your kids about Client Caching
Page 25: When to tell your kids about Client Caching

To illustrate: Scalability

Page 26: When to tell your kids about Client Caching
Page 27: When to tell your kids about Client Caching
Page 28: When to tell your kids about Client Caching
Page 29: When to tell your kids about Client Caching
Page 30: When to tell your kids about Client Caching

Applicable for?

Page 31: When to tell your kids about Client Caching

Applicable for?

Enterprises

Page 32: When to tell your kids about Client Caching

Applicable for?

Enterprises

High Traffic Web Sites

Page 33: When to tell your kids about Client Caching

Applicable for?

Enterprises

High Traffic Web Sites

Startups

Page 34: When to tell your kids about Client Caching

Enterprise

Page 35: When to tell your kids about Client Caching

High Traffic Sites

Page 36: When to tell your kids about Client Caching

Reduce network trafficReduce response timesReduce load

Page 37: When to tell your kids about Client Caching

Facebook: Bumpersticker

Page 38: When to tell your kids about Client Caching

1.4 Million Average Users

Page 39: When to tell your kids about Client Caching

1.4 Million Average Users

Average 20 page views

Page 40: When to tell your kids about Client Caching

“Push everything you possibly can to the client to reduce the amount of traffic going over the network...”

Page 41: When to tell your kids about Client Caching

Startups

Page 42: When to tell your kids about Client Caching
Page 43: When to tell your kids about Client Caching

HTTP 1.1 Enity Tags

Page 44: When to tell your kids about Client Caching
Page 45: When to tell your kids about Client Caching
Page 47: When to tell your kids about Client Caching

\puppies\43

Page 48: When to tell your kids about Client Caching

HTTP/1.x 200 OKEtag: "8b2242293d5e5b02e99b3be73fc0c9fa"

Page 49: When to tell your kids about Client Caching
Page 50: When to tell your kids about Client Caching
Page 52: When to tell your kids about Client Caching

If-None-Match: "8b2242293d5e5b02e99b3be73fc0c9fa"

\puppies\43

Page 53: When to tell your kids about Client Caching

HTTP/1.x 304 Not Modified

Page 54: When to tell your kids about Client Caching
Page 55: When to tell your kids about Client Caching
Page 56: When to tell your kids about Client Caching

Last-Modified: Tue, 12 Dec 2006 03:03:59 GMTETag: "10c24bc-4ab-457e1c1f"

Page 57: When to tell your kids about Client Caching

Last-Modified: Tue, 12 Dec 2006 03:03:59 GMTETag: "10c24bc-4ab-457e1c1f"

If-Modified-Since: Tue, 12 Dec 2006 03:03:59 GMTIf-None-Match: "10c24bc-4ab-457e1c1f"

Page 58: When to tell your kids about Client Caching

+ Conditional Get

Page 59: When to tell your kids about Client Caching

class PeopleController < ApplicationController def show @person = Person.find(params[:id])

respond_to do |wants| #... end end end

Page 60: When to tell your kids about Client Caching

#response.rb

def last_modified=(utc_time)def etag=(etag)

Page 61: When to tell your kids about Client Caching

#request.rb

def fresh?(response)def not_modified?(modified_at)def etag_matches?(etag)

Page 62: When to tell your kids about Client Caching

class PeopleController < ApplicationController def show @person = Person.find(params[:id])

respond_to do |wants| #... end end end

Page 63: When to tell your kids about Client Caching

class PeopleController < ApplicationController def show @person = Person.find(params[:id])

respond_to do |wants| #... end end end

response.last_modified = @person.updated_at.utc

Page 64: When to tell your kids about Client Caching

class PeopleController < ApplicationController def show @person = Person.find(params[:id])

respond_to do |wants| #... end end end

response.last_modified = @person.updated_at.utc response.etag = @person

Page 65: When to tell your kids about Client Caching

class PeopleController < ApplicationController def show @person = Person.find(params[:id])

respond_to do |wants| #... end end end

return head(:not_modified) if request.fresh?(response)

response.last_modified = @person.updated_at.utc response.etag = @person

Page 66: When to tell your kids about Client Caching

response.etag = @person # => “5cb44721b6ce18857ff6900486dc4aba”

@person.cache_key # => "people/5-20071224150000"

Page 67: When to tell your kids about Client Caching

def fresh_when(options)def stale?(options)

Page 68: When to tell your kids about Client Caching

class PeopleController < ApplicationController def show @person = Person.find(params[:id])

response.last_modified = @person.updated_at.utc response.etag = @person return head(:not_modified) if request.fresh?(response) respond_to do |wants| #... end end end

Page 69: When to tell your kids about Client Caching

class PeopleController < ApplicationController def show @person = Person.find(params[:id])

if stale?(:etag => @person, :last_modified => @person.updated_at.utc) respond_to do |wants| #... end end end end

Page 70: When to tell your kids about Client Caching

Last-Modified vs ETag

Page 71: When to tell your kids about Client Caching
Page 72: When to tell your kids about Client Caching
Page 73: When to tell your kids about Client Caching

response.etag = [@admin, @person, flash]

Later

Page 74: When to tell your kids about Client Caching

def handle_conditional_get! if nonempty_ok_response? self.etag ||= body if request && request.etag_matches?(etag) self.status = '304 Not Modified' self.body = '' end end

set_conditional_cache_control! if etag? || last_modified?end

Page 75: When to tell your kids about Client Caching

self.etag ||= body

SInce Feb 2007

Page 76: When to tell your kids about Client Caching
Page 77: When to tell your kids about Client Caching

http://localhost:3000/peopleGET /people HTTP/1.1

Page 78: When to tell your kids about Client Caching

http://localhost:3000/peopleGET /people HTTP/1.1

HTTP/1.x 200 OK...Etag: "94785662c6f60cb96681ed1b09a44783"

Page 79: When to tell your kids about Client Caching

http://localhost:3000/peopleGET /people HTTP/1.1

HTTP/1.x 200 OK...Etag: "94785662c6f60cb96681ed1b09a44783"

http://localhost:3000/peopleGET /people HTTP/1.1If-None-Match: "94785662c6f60cb96681ed1b09a44783"

Page 80: When to tell your kids about Client Caching

http://localhost:3000/peopleGET /people HTTP/1.1

HTTP/1.x 200 OK...Etag: "94785662c6f60cb96681ed1b09a44783"

http://localhost:3000/peopleGET /people HTTP/1.1If-None-Match: "94785662c6f60cb96681ed1b09a44783"

HTTP/1.x 304 Not ModifiedEtag: "94785662c6f60cb96681ed1b09a44783"

Page 81: When to tell your kids about Client Caching

send_file

Page 82: When to tell your kids about Client Caching
Page 83: When to tell your kids about Client Caching

Assets

Page 84: When to tell your kids about Client Caching

Assets

Page 85: When to tell your kids about Client Caching

Assets

Page 86: When to tell your kids about Client Caching

INODE

Page 87: When to tell your kids about Client Caching

/intl/en_ALL/images/logo.gif

ETag: "48b6a5bf-47f4-a0757"

Page 88: When to tell your kids about Client Caching

/intl/en_ALL/images/logo.gif

ETag: "48b6a5bf-47f4-a0757"

/intl/en_ALL/images/logo.gif

ETag: "48b6a5bf-61a-21c86a4"

Page 89: When to tell your kids about Client Caching

/intl/en_ALL/images/logo.gif

ETag: "48b6a5bf-47f4-a0757"

/intl/en_ALL/images/logo.gif

ETag: "48b6a5bf-61a-21c86a4"

Page 90: When to tell your kids about Client Caching

Avoid Cache Expiration & Validation

Page 91: When to tell your kids about Client Caching

/stylesheets/screen.css?1219926880

CACHE BUSTER!

Page 92: When to tell your kids about Client Caching

<FilesMatch "\.(pdf|flv|jpg|jpeg|png|gif|js|css|swf)$"> Header set Cache-Control "public" ExpiresActive On ExpiresDefault “access plus 10 years” FileETag None Header unset Last-Modified Header unset ETag</FilesMatch>

Now

Page 93: When to tell your kids about Client Caching

/images/beach.png?1241477547 /images/beach.png?1241477554

Server 1 Server 2

Page 94: When to tell your kids about Client Caching

Option 1

#config/environments/production.rb

#SubversionENV['RAILS_ASSET_ID'] = YAML::load(`svn info $RAILS_ROOT`)["Revision"].to_i

#GIT (Check out Grit too)ENV['RAILS_ASSET_ID'] = File.read(RAILS_ROOT + '/.git/refs/heads/deploy').chomp

Page 95: When to tell your kids about Client Caching

Option 2

task :finalize_update, :except => { :no_release => true } do stamp = Time.now.utc.strftime("%Y%m%d%H%M.%S") asset_paths = %w(images stylesheets javascripts).map do |asset| "#{latest_release}/public/#{p}" end.join(" ") run "find #{asset_paths} -exec touch -t #{stamp} {} ';'; true", :env => { "TZ" => "UTC" }end

Page 96: When to tell your kids about Client Caching

Option 2

#Capistrano 2.4set :normalize_asset_timestamps, true

Page 97: When to tell your kids about Client Caching

Option 3

Page 98: When to tell your kids about Client Caching

use-commit-times

Option 3

Page 99: When to tell your kids about Client Caching

Now

ActionView::Helpers::AssetTagHelper.cache_asset_timestamps = true

Page 100: When to tell your kids about Client Caching

Proxies & Via Header

Page 101: When to tell your kids about Client Caching

/stylesheets/screen.css?1219926880

/stylesheets/screen.1219926880.css

Bag of Tricks

Page 102: When to tell your kids about Client Caching

#asset_tag_helper.rbdef rewrite_asset_path(source) #... source + "?#{asset_id}" end

Page 103: When to tell your kids about Client Caching

#Rules for Versioned Static FilesRewriteRule ^(scripts|css|images)/(.+)\.(.+)\.(js|css|jpg|gif|png)$ $1/$2.$4 [L]

Page 104: When to tell your kids about Client Caching
Page 105: When to tell your kids about Client Caching

AJAX

Page 106: When to tell your kids about Client Caching

DUMB-ASSES

Page 107: When to tell your kids about Client Caching
Page 108: When to tell your kids about Client Caching

:method => :post

Page 109: When to tell your kids about Client Caching

:method => :post

Page 110: When to tell your kids about Client Caching

Superfluous values in URL

Page 111: When to tell your kids about Client Caching

Superfluous values in URL

Page 112: When to tell your kids about Client Caching

HTTP Headers

Page 113: When to tell your kids about Client Caching

HTTP Headers

Page 114: When to tell your kids about Client Caching

headers['Last-Modified'] = Time.now.httpdateheaders['Expires'] = '-1'headers['Pragma'] = 'no-cache'headers['Cache-Control'] = 'no-cache, must-revalidate, max-age=0, pre-check=0, post-check=0'

Page 115: When to tell your kids about Client Caching
Page 116: When to tell your kids about Client Caching

#http://github.com/dancroak/no_cacheno_cache :first_name_autocomplete, :index

Now

Page 117: When to tell your kids about Client Caching

Cache Ajax?

Page 118: When to tell your kids about Client Caching

Speed up rendering

Page 119: When to tell your kids about Client Caching

default 2 connections per host for HTTP 1.1

connections

Page 120: When to tell your kids about Client Caching

ActionController::Base.asset_host = "http://mt%d.google.com"

Page 121: When to tell your kids about Client Caching

ActionController::Base.asset_host = "http://mt%d.google.com"

http://mt0.google.com

http://mt1.google.com

http://mt2.google.com

http://mt3.google.com

Page 122: When to tell your kids about Client Caching

http://mt0.google.com http://mt1.google.com http://mt2.google.com http://mt3.google.com

CNAME Now

Page 123: When to tell your kids about Client Caching

greater than 40% drop in page load time

Page 124: When to tell your kids about Client Caching

host_names >= 2 && host_names <= 4

Page 125: When to tell your kids about Client Caching

# http://github.com/dhh/asset-hosting-with-minimum-ssl

config.action_controller.asset_host = AssetHostingWithMinimumSsl.new( # will serve non-SSL assetts on http://assets[1-4].example.com "http://assets%d.example.com", # will serve SSL assets on https://assets1.example.com "https://assets1.example.com" )

Now

Page 126: When to tell your kids about Client Caching

Less requests are better

Page 127: When to tell your kids about Client Caching

ActionController::Base.perform_caching = true

Combine Assets

Page 128: When to tell your kids about Client Caching

<%= javascript_include_tag 'application', 'user' %>

<script src="/javascripts/application.js?1219633350" type="text/javascript"></script><script src="/javascripts/user.js?1219633368" type="text/javascript"></script>

Page 129: When to tell your kids about Client Caching

<%= javascript_include_tag 'application', 'user', :cache => :true %>

<script src="/javascripts/all.js?1219633651" type="text/javascript"></script>

Page 130: When to tell your kids about Client Caching

<%= javascript_include_tag 'application', 'user', :cache=>‘login’ %>

<script src="/javascripts/login.js?1219633651" type="text/javascript"></script>

Page 131: When to tell your kids about Client Caching

application.js user.js

+login.js

Page 132: When to tell your kids about Client Caching
Page 133: When to tell your kids about Client Caching

Compiles on Server

Dedicated Asset Server / CDN

Not all servers may have login.js

Page 134: When to tell your kids about Client Caching

Timestamp Conflict

<script src="/javascripts/all.js?1219633651" type="text/javascript"></script> <script src="/javascripts/all.js?1219634734" type="text/javascript"></script>

Page 135: When to tell your kids about Client Caching

asset_packager || cramjam || CSSJSC

Page 136: When to tell your kids about Client Caching

Minify

Page 137: When to tell your kids about Client Caching

JSMIN || PackR

CSMINSmurfrucksack

minified_cache

YUI Compressor

http://compressorrater.thruhere.net/

Now

Page 138: When to tell your kids about Client Caching

bundle_fu

Page 139: When to tell your kids about Client Caching

<% bundle do %>

<%= javascript_include_tag "prototype" %> <%= stylesheet_link_tag "basic.css" %> <%= calendar_date_select_includes "red" %> <script src="javascripts/application.js" type="text/javascript"></script>

<% end %>

<script src="/javascripts/cache/bundle.js?1220211999" type="text/javascript"></script>

Page 140: When to tell your kids about Client Caching

Generates files locally during development

Page 141: When to tell your kids about Client Caching
Page 142: When to tell your kids about Client Caching

www.example.org dynamic contentstatic.example.org components (cookies don’t go here)

Page 143: When to tell your kids about Client Caching

www.example.org dynamic contentstatic.example.org components (cookies don’t go here)

Now

Page 144: When to tell your kids about Client Caching

CDN & Asset Servers

Page 145: When to tell your kids about Client Caching

Let Google be your CDN

Page 146: When to tell your kids about Client Caching
Page 147: When to tell your kids about Client Caching
Page 148: When to tell your kids about Client Caching
Page 149: When to tell your kids about Client Caching
Page 150: When to tell your kids about Client Caching
Page 151: When to tell your kids about Client Caching

Google Ajax Libraries

Page 152: When to tell your kids about Client Caching

jQuery

prototype

script.aculo.us

MooTools

dojo

Page 153: When to tell your kids about Client Caching

“Once we host a release of a given library, we are committed to hosting that release indefinitely”

Page 154: When to tell your kids about Client Caching

Last-Modified: Fri, 30 May 2008 06:03:19 GMTExpires: Sun, 17 Jan 2038 19:14:07 GMTCache-Control: publicDate: Sat, 30 Aug 2008 20:10:26 GMT

Page 155: When to tell your kids about Client Caching

Cache-Control: public

Page 156: When to tell your kids about Client Caching
Page 157: When to tell your kids about Client Caching

mod_deflate vs mod_gzip

Page 158: When to tell your kids about Client Caching

mod_deflate vs mod_gzipBaked w/ ApacheEasier on CPU~35% Compresion

Page 159: When to tell your kids about Client Caching

mod_deflate vs mod_gzipBaked w/ ApacheEasier on CPU~35% Compresion

~29% Compresion

Page 160: When to tell your kids about Client Caching

config.middleware.use Rack::Deflater

Page 161: When to tell your kids about Client Caching

GZip + Minification + Minimum Components

Page 162: When to tell your kids about Client Caching

Fewer Requests

Smaller Responses

Page 163: When to tell your kids about Client Caching

There is more potential for improvement by focusing on the front-end.

Cutting it in half reduces response times by 40% or more, whereas cutting back-end performance in half results in less than a 10% reduction.

Page 164: When to tell your kids about Client Caching

Front-end improvements typically require less time and resources than back-end projects (redesigning application architecture and code, finding

and optimizing critical code paths, adding or modifying hardware, distributing databases, etc.).

Page 165: When to tell your kids about Client Caching

yslowLiveHTTPHeaders

Fiddlerhttp://compressorrater.thruhere.net/

Page 166: When to tell your kids about Client Caching

Matthew Deiterswww.theAgileDeveloper.com