Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Rails Page Caching

7,201 views

Published on

Presentation given at the Feb '10 Nashville Ruby on Rails Meetup group.

Published in: Technology
  • Be the first to comment

  • Be the first to like this

Rails Page Caching

  1. 1. Rails Page Caching <ul><li>Travis Roberts </li></ul><ul><li>http://travisonrails.com </li></ul><ul><li>http://twitter.com/travisroberts </li></ul>
  2. 2. Why Cache? <ul><li>Significantly speed up page load. </li></ul><ul><li>Reduce resource usage on server. </li></ul>
  3. 3. But, How Do We Do It? <ul><li>in config/environments/development.rb </li></ul><ul><li>in app/controllers/[controller_name].rb </li></ul><ul><li>in config/environment.rb </li></ul>config.action_controller.perform_caching = true caches_page :index, :show, :feed # Move the cached files into their own directory config.action_controller.page_cache_directory = RAILS_ROOT + &quot;/public/cache/&quot;
  4. 4. What About New Content? <ul><li>New content won’t show, so we have to expire the cache </li></ul><ul><li>in config/environment.rb </li></ul><ul><li>This tells the application to load our “sweepers” dir </li></ul><ul><li>We put the expire logic in the sweepers </li></ul>config.load_paths += %W( #{RAILS_ROOT}/app/sweepers )
  5. 5. Quick and Dirty Sweeper class SiteSweeper < ActionController::Caching::Sweeper observe Post, Comment def after_save (record) self.class::sweep end def after_destroy (record) self.class::sweep end def self.sweep cache_dir = ActionController :: Base .page_cache_directory unless cache_dir == RAILS_ROOT + &quot;/public&quot; FileUtils .rm_r( Dir .glob(cache_dir + &quot;/*&quot; )) rescue Errno ::ENOENT RAILS_DEFAULT_LOGGER .info( &quot;Cache directory fully swept.&quot; ) end end end
  6. 6. We Can Do Better <ul><li>in app/sweepers/post_sweeper.rb </li></ul>class PostSweeper < ActionController::Caching::Sweeper observe Post def after_save (post) expire_pages(post) end def after_destroy (post) expire_pages(post) end def expire_pages (post) expire_page(blog_path(:page => nil )) # expire blog index (/blog/list) expire_page(blog_path(post)) # expire detail page (/blog/12) # if we need to remove an entire directory in the cache cache_dir = ActionController :: Base .page_cache_directory FileUtils .rm_r( Dir .glob(cache_dir + &quot;/blog/list/*&quot; )) rescue Errno ::ENOENT # expire list RAILS_DEFAULT_LOGGER .info( &quot;Cache directory for blog successfully swept.&quot; ) end end
  7. 7. Calling the Sweeper <ul><li>We need to tell our controller when to invoke the sweeper </li></ul><ul><li>in app/controllers/post_controller.rb </li></ul>class Manage::PostsController < ApplicationController cache_sweeper :post_sweeper, :only => [:create, :update, :destroy] # other code... end
  8. 8. Tell the Server to Use Cache <ul><li>Add the following lines to your .conf file </li></ul># Rewrite index to check for static index RewriteRule ^/$ /cache/index.html [QSA] # Rewrite to check for cached pages RewriteRule ^([^.]+)$ /cache/$1.html [QSA]
  9. 9. What about pagination? <ul><li>With default pagination, caching won’t work (site.com/blog?page=2) </li></ul><ul><li>We need to add a route for caching </li></ul>map.blog_list 'blog/list/:page' , :controller => 'blog' , :action => 'index' , :requirements => { :page => / d +/ }, :page => nil # This will add the following routes # blog_list_path => site.com/blog/list # blog_list_path(:page => 3) => site.com/blog/list/3
  10. 10. The End! <ul><li>Questions? </li></ul><ul><li>Comments? </li></ul>

×