Page Caching Resurrected: A Fairy Tale

Loading...

Flash Player 9 (or above) is needed to view presentations.
We have detected that you do not have it on your computer. To install it, go here.

0 comments

Post a comment

    Post a comment
    Embed Video
    Edit your comment Cancel

    Notes on slide 1





    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






    2 Favorites

    Page Caching Resurrected: A Fairy Tale - Presentation 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=\"pig-list\"> <% @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[\"PATH_INFO\"] =~ /^\\/threaten/ [ 200, {\"Content-Type\" => \"text/html\"}, \"Little pig, little pig, let me in!\" ] else [ 404, {\"Content-Type\" => \"text/html\"}, \"Not Found\" ] 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=\"text/javascript\" charset=\"utf-8\">/*<![CDATA[*/ Event.observe(window, \"load\", function() { Behaviors.onLoad(); Behaviors.setLoggedIn(); Login.setup(); if ($(\"login\") && $(\"login-form\")) { 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 = \"https://secure.hulu.com/account/authenticate\" + '?' + ... el.appendChild(script); } } /*]]>*/</script> Sunday, March 22, 2009
    45. <ul id=\"logged-in-nav\" class=\"usernav\" style=\"display:none\"> <li id=\"welcome-username\" class=\"first\"> Welcome </li> <li> <a href=\"/profile\" class=\"utility-link\">Profile</a> </li> <li> <a href=\"/profile/queue\" class=\"utility-link\" id=\"your-queue-link\">Queue</a> </li> <li class=\"sign-out-link\"> <a href=\"#\" id=\"top-nav-sign-out\" onclick=\"new Ajax.Request(...)\">Sign Out</a> </li> </ul> <ul id=\"logged-out-nav\" class=\"usernav\" style=\"display:none\"> <li class=\"first sign-out-link\"> <a class=\"utility-link\" href=\"#\" id=\"login-link\" onclick=\"Login.show($('top-login-form')); return false;\">Login</a> </li> <li class=\"signin-border-left\"> <a href=\"/users/forgot_password\" class=\"utility-link\">Forgot Password?</a> </li> <li class=\"signin-border-left\"> <a href=\"/signup\" class=\"utility-link\">Sign Up</a> </li> </ul> Sunday, March 22, 2009
    46. <noscript> <ul class=\"nojs usernav\"> <li> Please <a href=\"/support/\">enable javascript</a> to log in. </li> </ul> </noscript> <div id=\"top-login-form\" class=\"usernav login-form\" style=\"display:none\"> <form action=\"https://secure.hulu.com/account/authenticate\" method=\"get\" name=\"login-form\" onsubmit=\"Login.submit(this); return false;\"> <span class=\"login-status\"></span> <input id=\"login\" class=\"active login\" type=\"text\" style=\"display: none;\" name=\"username\"/> <input id=\"password\" class=\"active password\" type=\"password\" style=\"display: none;\" name=\"password\"/> <input class=\"inactive dummy login\" type=\"text\" value=\"username\" name=\"dummy_login\" /> <input class=\"inactive dummy\" type=\"text\" value=\"password\" name=\"dummy_password\" /> <input alt=\"Login\" class=\"login-submit\" src=\"http://static.hulu.com/images/btn-signin-small.gif?1237361096\" style=\"width: 39px; height: 20;\" type=\"image\" /> <a href=\"#\"><img alt=\"Cancel\" border=\"0\" class=\"hover-me\" height=\"20\" id=\"btn-x.gif123741536309506\" onclick=\"Login.cancel();return false\" src=\"http://static.hulu.com/images/btn-x.gif?1237361096\" width=\"18\" /></a> </form> <a href=\"/signup\" class=\"utility-link\">Sign Up</a> </div> Sunday, March 22, 2009
    47. <ul id=\"logged-in-nav\" class=\"usernav\" style=\"display:none\"> <li id=\"welcome-username\" class=\"first\"> Welcome </li> <li> <a href=\"/profile\" class=\"utility-link\">Profile</a> </li> <li> <a href=\"/profile/queue\" class=\"utility-link\" id=\"your-queue-link\">Queue</a> </li> <li class=\"sign-out-link\"> <a href=\"#\" id=\"top-nav-sign-out\" onclick=\"new Ajax.Request(...)\">Sign Out</a> </li> </ul> <ul id=\"logged-out-nav\" class=\"usernav\" style=\"display:none\"> <li class=\"first sign-out-link\"> <a class=\"utility-link\" href=\"#\" id=\"login-link\" onclick=\"Login.show($('top-login-form')); return false;\">Login</a> </li> <li class=\"signin-border-left\"> <a href=\"/users/forgot_password\" class=\"utility-link\">Forgot Password?</a> </li> <li class=\"signin-border-left\"> <a href=\"/signup\" class=\"utility-link\">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=\"text/javascript\" charset=\"utf-8\">/*<![CDATA[*/ Event.observe(window, \"load\", function() { Behaviors.onLoad(); Behaviors.setLoggedIn(); Login.setup(); if ($(\"login\") && $(\"login-form\")) { 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 = \"https://secure.hulu.com/account/authenticate\" + '?' + ... el.appendChild(script); } } /*]]>*/</script> Sunday, March 22, 2009
    51. <script type=\"text/javascript\" charset=\"utf-8\">/*<![CDATA[*/ Event.observe(window, \"load\", function() { Behaviors.onLoad(); Behaviors.setLoggedIn(); Login.setup(); if ($(\"login\") && $(\"login-form\")) { 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 = \"https://secure.hulu.com/account/authenticate\" + '?' + ... 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__) + \"/../../config/environment\") unless defined?(Rails) class PullList def self.call(env) if env[\"PATH_INFO\"] =~ /^\\/pulls/ date = '2008-11-05' user = '1' [ 200, {\"Content-Type\" => \"application/javascript\"}, [Pull.by_user(user).for_date(date).map {|i| i.item_id}.to_json]] else [404, {\"Content-Type\" => \"text/html\"}, [\"Not Found\"]] 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

    + Ben ScofieldBen Scofield, 7 months ago

    custom

    540 views, 2 favs, 0 embeds more stats

    Presentation given at the first Developer Day, in D more

    More info about this document

    © All Rights Reserved

    Go to text version

    • Total Views 540
      • 540 on SlideShare
      • 0 from embeds
    • Comments 0
    • Favorites 2
    • Downloads 6
    Most viewed embeds

    more

    All embeds

    less

    Flagged as inappropriate Flag as inappropriate
    Flag as inappropriate

    Select your reason for flagging this presentation as inappropriate. If needed, use the feedback form to let us know more details.

    Cancel
    File a copyright complaint
    Having problems? Go to our helpdesk?

    Categories