1 如果在开发模式下,缓寸是不可用的,需要改动配制启动缓存,在/config/environments/development.rb中设置
config.action_controller.perform_caching = true;
2 页面缓存
页面缓存是Rails最为FASTEST的缓存机制,符合页面缓存的两种情况:
* 如果同一页面对所有用户是相同的(If your page is the same for all users.)
* If your page is available to the public, with no authentication needed.
如果我的blog侧栏要显示最近的10篇文章。右不经常改动。为了提高性能,我可以把它缓存起来。
class BlogController < ApplicationController caches_page :list def list Post.find(:all, :order => "created_on desc", :limit => 10) end ...
caches_page告诉程序第一次"list"action被请求时,取得html结果,并存储在缓存文件里。
The "caches_page" directive tells our application that next time the "list" action is requested, take the resulting html, and store it in a cached file.
如过在mongrel中运行,第一次请求时在/logs/development.log文件中看到的日志为:
Processing BlogController#list (for 127.0.0.1 at 2007-02-23 00:58:56) [GET]
Parameters: {"action"=>"list", "controller"=>"blog"}
SELECT * FROM posts ORDER BY created_on LIMIT 10
Rendering blog/list
Cached page: /blog/list.html (0.00000) 表示缓存文件被存储了。存储的位置在/public/blog/list.html
Completed in 0.18700 (5 reqs/sec) | Rendering: 0.10900 (58%) | DB: 0.00000 (0%) | 200 OK [http://localhost/blog/list]
缓存后,如果再次请求,就直接利用缓存的结果,这样比再次解释执行代码快上100倍
同样的有:
http://localhost:3000/blog/list => /public/blog/list.html http://localhost:3000/blog/edit/5 => /public/edit/5.html http://localhost:3000/blog => /public/blog.html http://localhost:3000/ => /public/index.html http://localhost:3000/blog/list?page=2 => /public/blog/list.html
3 怎样缓存分页页面:
因为缓存会忽略额外的参数,所以形如:"/blog/list?page=2"得不到想要的结果的,应该该成'/blog/list/2',这就需要配置特殊的路由了。
map.connect 'blog/list/:page', :controller => 'blog', :action => 'list', :requirements => { :page => /\d+/}, :page => nil <%= link_to "Next Page", :controller => 'blog', :action => 'list', :page => 2 %>
以上的方法就能解决分页缓存的问题了。
4清除缓存
如果新增了一篇blog后,希望能更新在侧栏的最进10篇文章
解决的方法是执行:
expire_page(:controller => 'blog', :action => 'list')
同样有
expire_page(:controller => 'blog', :action => 'show', :id => 5)
5Sweepers
Sweepers是一段代码,帮你自动清除内容以太旧的缓存文件,sweepers观察observe我们的一个或多个(model),当model被添加/更新/删除时sweeper会得到通知,然后运行我们所期望的代码:
Sweepers可以在controllers目录中创建,但还是可以添加到/config/environment.rb.
Rails::Initializer.run do |config| # ... config.load_paths += %W( #{RAILS_ROOT}/app/sweepers ) # ... end
最好的方法是另外创建一个目录sweepers,把代码写在sweepers/blog_sweeper.rb文件中
class BlogSweeper < ActionController::Caching::Sweeper observe Post # This sweeper is going to keep an eye on the Post model # If our sweeper detects that a Post was created call this def after_create(post) expire_cache_for(post) end # If our sweeper detects that a Post was updated call this def after_update(post) expire_cache_for(post) end # If our sweeper detects that a Post was deleted call this def after_destroy(post) expire_cache_for(post) end private def expire_cache_for(record) # Expire the list page now that we posted a new blog entry expire_page(:controller => 'blog', :action => 'list') # Also expire the show page, incase we just edited a blog entry expire_page(:controller => 'blog', :action => 'show', :id => record.id) end end
下一步我们需要告诉controller当sweeper激活时
class BlogController < ApplicationController caches_page :list, :show cache_sweeper :blog_sweeper, :only => [:create, :update, :destroy]