Your SlideShare is downloading. ×
0
Page Caching Resurrected: A Fairy Tale
Page Caching Resurrected: A Fairy Tale
Page Caching Resurrected: A Fairy Tale
Page Caching Resurrected: A Fairy Tale
Page Caching Resurrected: A Fairy Tale
Page Caching Resurrected: A Fairy Tale
Page Caching Resurrected: A Fairy Tale
Page Caching Resurrected: A Fairy Tale
Page Caching Resurrected: A Fairy Tale
Page Caching Resurrected: A Fairy Tale
Page Caching Resurrected: A Fairy Tale
Page Caching Resurrected: A Fairy Tale
Page Caching Resurrected: A Fairy Tale
Page Caching Resurrected: A Fairy Tale
Page Caching Resurrected: A Fairy Tale
Page Caching Resurrected: A Fairy Tale
Page Caching Resurrected: A Fairy Tale
Page Caching Resurrected: A Fairy Tale
Page Caching Resurrected: A Fairy Tale
Page Caching Resurrected: A Fairy Tale
Page Caching Resurrected: A Fairy Tale
Page Caching Resurrected: A Fairy Tale
Page Caching Resurrected: A Fairy Tale
Page Caching Resurrected: A Fairy Tale
Page Caching Resurrected: A Fairy Tale
Page Caching Resurrected: A Fairy Tale
Page Caching Resurrected: A Fairy Tale
Page Caching Resurrected: A Fairy Tale
Page Caching Resurrected: A Fairy Tale
Page Caching Resurrected: A Fairy Tale
Page Caching Resurrected: A Fairy Tale
Page Caching Resurrected: A Fairy Tale
Page Caching Resurrected: A Fairy Tale
Page Caching Resurrected: A Fairy Tale
Page Caching Resurrected: A Fairy Tale
Page Caching Resurrected: A Fairy Tale
Page Caching Resurrected: A Fairy Tale
Page Caching Resurrected: A Fairy Tale
Page Caching Resurrected: A Fairy Tale
Page Caching Resurrected: A Fairy Tale
Page Caching Resurrected: A Fairy Tale
Page Caching Resurrected: A Fairy Tale
Page Caching Resurrected: A Fairy Tale
Page Caching Resurrected: A Fairy Tale
Page Caching Resurrected: A Fairy Tale
Page Caching Resurrected: A Fairy Tale
Page Caching Resurrected: A Fairy Tale
Page Caching Resurrected: A Fairy Tale
Page Caching Resurrected: A Fairy Tale
Page Caching Resurrected: A Fairy Tale
Page Caching Resurrected: A Fairy Tale
Page Caching Resurrected: A Fairy Tale
Page Caching Resurrected: A Fairy Tale
Page Caching Resurrected: A Fairy Tale
Page Caching Resurrected: A Fairy Tale
Page Caching Resurrected: A Fairy Tale
Page Caching Resurrected: A Fairy Tale
Page Caching Resurrected: A Fairy Tale
Page Caching Resurrected: A Fairy Tale
Page Caching Resurrected: A Fairy Tale
Page Caching Resurrected: A Fairy Tale
Page Caching Resurrected: A Fairy Tale
Page Caching Resurrected: A Fairy Tale
Page Caching Resurrected: A Fairy Tale
Page Caching Resurrected: A Fairy Tale
Page Caching Resurrected: A Fairy Tale
Page Caching Resurrected: A Fairy Tale
Page Caching Resurrected: A Fairy Tale
Page Caching Resurrected: A Fairy Tale
Page Caching Resurrected: A Fairy Tale
Page Caching Resurrected: A Fairy Tale
Page Caching Resurrected: A Fairy Tale
Page Caching Resurrected: A Fairy Tale
Page Caching Resurrected: A Fairy Tale
Page Caching Resurrected: A Fairy Tale
Page Caching Resurrected: A Fairy Tale
Page Caching Resurrected: A Fairy Tale
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×
Saving this for later? Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime – even offline.
Text the download link to your phone
Standard text messaging rates apply

Page Caching Resurrected: A Fairy Tale

825

Published on

Presentation given at the first Developer Day, in Durham NC on March 21st, 2009

Presentation given at the first Developer Day, in Durham NC on March 21st, 2009

Published in: Technology, News & Politics
0 Comments
3 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
825
On Slideshare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
Downloads
14
Comments
0
Likes
3
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide




  • 3 minutes



  • super simple to use, but results in PUBLIC content




  • more framework-specific; solves auth-protected pages, etc. - cached content is not publicly available





  • caches only specific parts of the page, which are not publically available
  • expiration of each fragment, individually


  • 10 minutes








  • 15 minutes










  • 22 minutes






  • 26 minutes




  • 32 minutes



  • 135ms for hybrid, which is 21% of the standard

    lame tests I employed showed the same or greater effect
  • 34 minutes





  • Transcript

    • 1. Page Caching Resurrected: Ben Sco eld – Viget Labs Sunday, March 22, 2009
    • 2. Page Caching Resurrected: A Fairy Tale Ben Sco eld – Viget Labs Sunday, March 22, 2009
    • 3. I’m a Rails guy Sunday, March 22, 2009
    • 4. and this is a Rails talk Sunday, March 22, 2009
    • 5. but this isn’t just for Rails Sunday, March 22, 2009
    • 6. the story Sunday, March 22, 2009
    • 7. Sunday, March 22, 2009
    • 8. page caching Sunday, March 22, 2009
    • 9. Sunday, March 22, 2009
    • 10. Sunday, March 22, 2009
    • 11. class PigsController caches_page :show def show @pig = Pig.find(params[:id]) end def update @pig = Pig.find(params[:id]) @pig.update_attributes(params[:pig]) expire_page :action => :show end end Sunday, March 22, 2009
    • 12. Standard 1 Page 3000 requests per second Sunday, March 22, 2009
    • 13. public dynamic content Sunday, March 22, 2009
    • 14. action caching Sunday, March 22, 2009
    • 15. Sunday, March 22, 2009
    • 16. Sunday, March 22, 2009
    • 17. class PigsController require_login :show caches_action :show def show @pig = Pig.find(params[:id]) end def update @pig = Pig.find(params[:id]) @pig.update_attributes(params[:pig]) expire_action :action => :show end end Sunday, March 22, 2009
    • 18. Standard 1 Action 500 Page 3000 requests per second Sunday, March 22, 2009
    • 19. dynamic content Sunday, March 22, 2009
    • 20. fragment caching Sunday, March 22, 2009
    • 21. Sunday, March 22, 2009
    • 22. Sunday, March 22, 2009
    • 23. Sunday, March 22, 2009
    • 24. Sunday, March 22, 2009
    • 25. <% cache(:key => 'index:piglist') do %> <ul id=quot;pig-listquot;> <% @pigs.each do |pig| %> <li> <%= image_tag pig.house.photo %> <%= h pig.name %> </li> <% end %> </ul> <% end %> Sunday, March 22, 2009
    • 26. class PigsController # ... def update @pig = Pig.find(params[:id]) @pig.update_attributes(params[:pig]) expire_fragment :key => 'index:piglist' end end Sunday, March 22, 2009
    • 27. Standard 1 Fragment 20 Action 500 Page 3000 requests per second Sunday, March 22, 2009
    • 28. efficiency Sunday, March 22, 2009
    • 29. the idea Sunday, March 22, 2009
    • 30. Rails 2.3 Sunday, March 22, 2009
    • 31. hello, metal Sunday, March 22, 2009
    • 32. class BigBadWolf def self.call(env) if env[quot;PATH_INFOquot;] =~ /^/threaten/ [ 200, {quot;Content-Typequot; => quot;text/htmlquot;}, quot;Little pig, little pig, let me in!quot; ] else [ 404, {quot;Content-Typequot; => quot;text/htmlquot;}, quot;Not Foundquot; ] end end end Sunday, March 22, 2009
    • 33. high-performance endpoints Sunday, March 22, 2009
    • 34. AJAX Sunday, March 22, 2009
    • 35. so... Sunday, March 22, 2009
    • 36. javascript Sunday, March 22, 2009
    • 37. Sunday, March 22, 2009
    • 38. Sunday, March 22, 2009
    • 39. Sunday, March 22, 2009
    • 40. Sunday, March 22, 2009
    • 41. Sunday, March 22, 2009
    • 42. Sunday, March 22, 2009
    • 43. Sunday, March 22, 2009
    • 44. <script type=quot;text/javascriptquot; charset=quot;utf-8quot;>/*<![CDATA[*/ Event.observe(window, quot;loadquot;, function() { Behaviors.onLoad(); Behaviors.setLoggedIn(); Login.setup(); if ($(quot;loginquot;) && $(quot;login-formquot;)) { Event.observe('login', 'keydown', function(ev) { if (ev.keyCode == 13) { Login.submit(); } }); } }); Login.auth = function(login, password) { document.cookie = 'login=' + login + '; path=/account/authenticate; secure; ... document.cookie = 'password=' + password + '; path=/account/authenticate; ... el = $$('body').first(); if (el) { var script = document.createElement('script'); script.type = 'text/javascript'; script.src = quot;https://secure.hulu.com/account/authenticatequot; + '?' + ... el.appendChild(script); } } /*]]>*/</script> Sunday, March 22, 2009
    • 45. <ul id=quot;logged-in-navquot; class=quot;usernavquot; style=quot;display:nonequot;> <li id=quot;welcome-usernamequot; class=quot;firstquot;> Welcome </li> <li> <a href=quot;/profilequot; class=quot;utility-linkquot;>Profile</a> </li> <li> <a href=quot;/profile/queuequot; class=quot;utility-linkquot; id=quot;your-queue-linkquot;>Queue</a> </li> <li class=quot;sign-out-linkquot;> <a href=quot;#quot; id=quot;top-nav-sign-outquot; onclick=quot;new Ajax.Request(...)quot;>Sign Out</a> </li> </ul> <ul id=quot;logged-out-navquot; class=quot;usernavquot; style=quot;display:nonequot;> <li class=quot;first sign-out-linkquot;> <a class=quot;utility-linkquot; href=quot;#quot; id=quot;login-linkquot; onclick=quot;Login.show($('top-login-form')); return false;quot;>Login</a> </li> <li class=quot;signin-border-leftquot;> <a href=quot;/users/forgot_passwordquot; class=quot;utility-linkquot;>Forgot Password?</a> </li> <li class=quot;signin-border-leftquot;> <a href=quot;/signupquot; class=quot;utility-linkquot;>Sign Up</a> </li> </ul> Sunday, March 22, 2009
    • 46. <noscript> <ul class=quot;nojs usernavquot;> <li> Please <a href=quot;/support/quot;>enable javascript</a> to log in. </li> </ul> </noscript> <div id=quot;top-login-formquot; class=quot;usernav login-formquot; style=quot;display:nonequot;> <form action=quot;https://secure.hulu.com/account/authenticatequot; method=quot;getquot; name=quot;login-formquot; onsubmit=quot;Login.submit(this); return false;quot;> <span class=quot;login-statusquot;></span> <input id=quot;loginquot; class=quot;active loginquot; type=quot;textquot; style=quot;display: none;quot; name=quot;usernamequot;/> <input id=quot;passwordquot; class=quot;active passwordquot; type=quot;passwordquot; style=quot;display: none;quot; name=quot;passwordquot;/> <input class=quot;inactive dummy loginquot; type=quot;textquot; value=quot;usernamequot; name=quot;dummy_loginquot; /> <input class=quot;inactive dummyquot; type=quot;textquot; value=quot;passwordquot; name=quot;dummy_passwordquot; /> <input alt=quot;Loginquot; class=quot;login-submitquot; src=quot;http://static.hulu.com/images/btn-signin-small.gif?1237361096quot; style=quot;width: 39px; height: 20;quot; type=quot;imagequot; /> <a href=quot;#quot;><img alt=quot;Cancelquot; border=quot;0quot; class=quot;hover-mequot; height=quot;20quot; id=quot;btn-x.gif123741536309506quot; onclick=quot;Login.cancel();return falsequot; src=quot;http://static.hulu.com/images/btn-x.gif?1237361096quot; width=quot;18quot; /></a> </form> <a href=quot;/signupquot; class=quot;utility-linkquot;>Sign Up</a> </div> Sunday, March 22, 2009
    • 47. <ul id=quot;logged-in-navquot; class=quot;usernavquot; style=quot;display:nonequot;> <li id=quot;welcome-usernamequot; class=quot;firstquot;> Welcome </li> <li> <a href=quot;/profilequot; class=quot;utility-linkquot;>Profile</a> </li> <li> <a href=quot;/profile/queuequot; class=quot;utility-linkquot; id=quot;your-queue-linkquot;>Queue</a> </li> <li class=quot;sign-out-linkquot;> <a href=quot;#quot; id=quot;top-nav-sign-outquot; onclick=quot;new Ajax.Request(...)quot;>Sign Out</a> </li> </ul> <ul id=quot;logged-out-navquot; class=quot;usernavquot; style=quot;display:nonequot;> <li class=quot;first sign-out-linkquot;> <a class=quot;utility-linkquot; href=quot;#quot; id=quot;login-linkquot; onclick=quot;Login.show($('top-login-form')); return false;quot;>Login</a> </li> <li class=quot;signin-border-leftquot;> <a href=quot;/users/forgot_passwordquot; class=quot;utility-linkquot;>Forgot Password?</a> </li> <li class=quot;signin-border-leftquot;> <a href=quot;/signupquot; class=quot;utility-linkquot;>Sign Up</a> </li> </ul> Sunday, March 22, 2009
    • 48. Sunday, March 22, 2009
    • 49. hulu is insane don’t do it like they do Sunday, March 22, 2009
    • 50. <script type=quot;text/javascriptquot; charset=quot;utf-8quot;>/*<![CDATA[*/ Event.observe(window, quot;loadquot;, function() { Behaviors.onLoad(); Behaviors.setLoggedIn(); Login.setup(); if ($(quot;loginquot;) && $(quot;login-formquot;)) { Event.observe('login', 'keydown', function(ev) { if (ev.keyCode == 13) { Login.submit(); } }); } }); Login.auth = function(login, password) { document.cookie = 'login=' + login + '; path=/account/authenticate; secure; ... document.cookie = 'password=' + password + '; path=/account/authenticate; ... el = $$('body').first(); if (el) { var script = document.createElement('script'); script.type = 'text/javascript'; script.src = quot;https://secure.hulu.com/account/authenticatequot; + '?' + ... el.appendChild(script); } } /*]]>*/</script> Sunday, March 22, 2009
    • 51. <script type=quot;text/javascriptquot; charset=quot;utf-8quot;>/*<![CDATA[*/ Event.observe(window, quot;loadquot;, function() { Behaviors.onLoad(); Behaviors.setLoggedIn(); Login.setup(); if ($(quot;loginquot;) && $(quot;login-formquot;)) { Event.observe('login', 'keydown', function(ev) { if (ev.keyCode == 13) { Login.submit(); } }); } }); Login.auth = function(login, password) { document.cookie = 'login=' + login + '; path=/account/authenticate; secure; ... document.cookie = 'password=' + password + '; path=/account/authenticate; ... el = $$('body').first(); if (el) { var script = document.createElement('script'); script.type = 'text/javascript'; script.src = quot;https://secure.hulu.com/account/authenticatequot; + '?' + ... el.appendChild(script); } } /*]]>*/</script> Sunday, March 22, 2009
    • 52. the* right way *a Sunday, March 22, 2009
    • 53. Sunday, March 22, 2009
    • 54. Sunday, March 22, 2009
    • 55. the standard approach Sunday, March 22, 2009
    • 56. class ItemsController < ApplicationController def index @user = User.find_by_login(params[:user]) @items = Item.released_on(params[:date]) end end Sunday, March 22, 2009
    • 57. class Item < ActiveRecord::Base has_many :pulls, :dependent => :destroy named_scope :released_on, lambda { |date| date ||= Item.maximum(:released_on) {:conditions => {:released_on => date}, :order => 'name ASC'} } def pulled_by?(user) x = user.nil? ? false : !self.pulls.by_user(user.id).empty? end end Sunday, March 22, 2009
    • 58. <h1>Releases</h1> <ul> <% @items.each do |item| %> <% content_tag_for :li, item do %> <%= image_tag 'cover.png', :alt => h(item.name), :class => 'cover' %> <%= image_tag('badge.png', :alt => 'pulling',:class => 'badge') if item.pulled_by?(@user) %> <p><%= h item.name %></p> <% end %> <% end %> </ul> Sunday, March 22, 2009
    • 59. the hybrid approach Sunday, March 22, 2009
    • 60. class ItemsController < ApplicationController caches_page :index def index @items = Item.released_on(params[:date]).all end end Sunday, March 22, 2009
    • 61. require(File.dirname(__FILE__) + quot;/../../config/environmentquot;) unless defined?(Rails) class PullList def self.call(env) if env[quot;PATH_INFOquot;] =~ /^/pulls/ date = '2008-11-05' user = '1' [ 200, {quot;Content-Typequot; => quot;application/javascriptquot;}, [Pull.by_user(user).for_date(date).map {|i| i.item_id}.to_json]] else [404, {quot;Content-Typequot; => quot;text/htmlquot;}, [quot;Not Foundquot;]] end end end Sunday, March 22, 2009
    • 62. class Pull < ActiveRecord::Base belongs_to :user belongs_to :item named_scope :by_user, lambda { |user_id| {:conditions => {:user_id => user_id}} } named_scope :for_date, lambda { |date| {:include => :item, :conditions => {:items => {:released_on => date}}} } end Sunday, March 22, 2009
    • 63. $(document).ready(function() { $.getJSON('/pulls', function(data) { $.each(data, function() { $('#item_'+this).addClass('pulled'); }); }); }); Sunday, March 22, 2009
    • 64. the payoff Sunday, March 22, 2009
    • 65. Sunday, March 22, 2009
    • 66. standard Sunday, March 22, 2009
    • 67. hybrid Sunday, March 22, 2009
    • 68. Standard 0.617 Hybrid 0.039 0.096 content load time Sunday, March 22, 2009
    • 69. when to use it Sunday, March 22, 2009
    • 70. Sunday, March 22, 2009
    • 71. Sunday, March 22, 2009
    • 72. Sunday, March 22, 2009
    • 73. Sunday, March 22, 2009
    • 74. Sunday, March 22, 2009
    • 75. Sunday, March 22, 2009
    • 76. no shirt, no javascript, no service Sunday, March 22, 2009
    • 77. Thank You ben sco eld - @bsco eld - http://www.viget.com/extend - http://www.speakerrate.com/speakers/44 Sunday, March 22, 2009

    ×