when to tell your kids about presentation caching
play

When to tell your kids about presentation caching Matthew Deiters - PowerPoint PPT Presentation

When to tell your kids about presentation caching Matthew Deiters www.theAgileDeveloper.com A practical guide to stuffing your apps bits into someone elses browser Questions: @mdeiters Rapid Feature Development Rapid Feature


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

  2. A practical guide to stuffing your app’s bits into someone else’s browser

  3. Questions: @mdeiters

  4. Rapid Feature Development

  5. Rapid Feature Adoption & Development Growth

  6. Client Caching

  7. client.is_a?(Browser) == true

  8. Browsers & Leveraging HTTP 1.1

  9. Fewer Requests Smaller Responses

  10. 80/20 Rule (Pareto Principle)

  11. 80% of the wealth owned by 20% of people

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

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

  14. 80% of a request is spent on the wire

  15. Today

  16. Reducing Network Tra � c Last-Modified Header ETag Header GZip Today Minification max-age Header Cookies Expires Header

  17. ME

  18. To illustrate: Scalability

  19. Applicable for?

  20. Applicable for? Enterprises

  21. Applicable for? Enterprises High Traffic Web Sites

  22. Applicable for? Enterprises High Traffic Web Sites Startups

  23. Enterprise

  24. High Traffic Sites

  25. Reduce network traffic Reduce response times Reduce load

  26. Facebook: Bumpersticker

  27. 1.4 Million Average Users

  28. 1.4 Million Average Users Average 20 page views

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

  30. Startups

  31. HTTP 1.1 Enity Tags

  32. www.nextdaypets.com

  33. \puppies\43

  34. HTTP/1.x 200 OK Etag: "8b2242293d5e5b02e99b3be73fc0c9fa"

  35. www.nextdaypets.com

  36. \puppies\43 If-None-Match: "8b2242293d5e5b02e99b3be73fc0c9fa"

  37. HTTP/1.x 304 Not Modified

  38. Last-Modified: Tue, 12 Dec 2006 03:03:59 GMT ETag: "10c24bc-4ab-457e1c1f"

  39. Last-Modified: Tue, 12 Dec 2006 03:03:59 GMT ETag: "10c24bc-4ab-457e1c1f" If-Modified-Since: Tue, 12 Dec 2006 03:03:59 GMT If-None-Match: "10c24bc-4ab-457e1c1f"

  40. + Conditional Get

  41. class PeopleController < ApplicationController def show @person = Person.find(params[:id]) respond_to do |wants| #... end end end

  42. #response.rb def last_modified=(utc_time) def etag=(etag)

  43. #request.rb def fresh?(response) def not_modified?(modified_at) def etag_matches?(etag)

  44. class PeopleController < ApplicationController def show @person = Person.find(params[:id]) respond_to do |wants| #... end end end

  45. class PeopleController < ApplicationController def show @person = Person.find(params[:id]) response.last_modified = @person.updated_at.utc respond_to do |wants| #... end end end

  46. class PeopleController < ApplicationController def show @person = Person.find(params[:id]) response.last_modified = @person.updated_at.utc response.etag = @person respond_to do |wants| #... end end end

  47. 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

  48. response.etag = @person # => “5cb44721b6ce18857ff6900486dc4aba” @person.cache_key # => "people/5-20071224150000"

  49. def fresh_when(options) def stale?(options)

  50. 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

  51. 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

  52. Last-Modified vs ETag

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

  54. 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

  55. SInce Feb 2007 self.etag ||= body

  56. http://localhost:3000/people GET /people HTTP/1.1

  57. http://localhost:3000/people GET /people HTTP/1.1 HTTP/1.x 200 OK ... Etag: "94785662c6f60cb96681ed1b09a44783"

  58. http://localhost:3000/people GET /people HTTP/1.1 HTTP/1.x 200 OK ... Etag: "94785662c6f60cb96681ed1b09a44783" http://localhost:3000/people GET /people HTTP/1.1 If-None-Match: "94785662c6f60cb96681ed1b09a44783"

  59. http://localhost:3000/people GET /people HTTP/1.1 HTTP/1.x 200 OK ... Etag: "94785662c6f60cb96681ed1b09a44783" http://localhost:3000/people GET /people HTTP/1.1 If-None-Match: "94785662c6f60cb96681ed1b09a44783" HTTP/1.x 304 Not Modified Etag: "94785662c6f60cb96681ed1b09a44783"

  60. send_file

  61. Assets

  62. Assets

  63. Assets

  64. INODE

  65. /intl/en_ALL/images/logo.gif ETag: "48b6a5bf-47f4-a0757"

  66. /intl/en_ALL/images/logo.gif /intl/en_ALL/images/logo.gif ETag: "48b6a5bf-47f4-a0757" ETag: "48b6a5bf-61a-21c86a4"

  67. /intl/en_ALL/images/logo.gif /intl/en_ALL/images/logo.gif ETag: "48b6a5bf-47f4-a0757" ETag: "48b6a5bf-61a-21c86a4"

  68. Avoid Cache Expiration & Validation

  69. /stylesheets/screen.css?1219926880 CACHE BUSTER!

  70. Now <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>

  71. Server 1 Server 2 /images/beach.png?12414775 47 /images/beach.png?12414775 54

  72. Option 1 #config/environments/production.rb #Subversion ENV['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

  73. 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

  74. Option 2 #Capistrano 2.4 set :normalize_asset_timestamps, true

  75. Option 3

  76. Option 3 use-commit-times

  77. Now ActionView::Helpers::AssetTagHelper.cache_asset_timestamps = true

  78. Proxies & Via Header

Recommend


More recommend