Displaying articles with tag page caching

Ruby on Rails :: Page caching

Posted by PunNeng, Mon Oct 06 01:17:00 UTC 2008

รีบปั่นก่อน ก่อนที่ merb 1.0 จะออกมา เดี๋ยวจะไม่ได้เขียน blog สักเท่าไหร่ เพราะคงไปนั่งวุ่นอยู่กับ merb นี่แหละ

post อันนี้ คงจะอยู่ทั้ง blog ผม และ rails66.com ด้วย เขียนทีเดียว แปะมันทั้งสองที่

วิธีการทีจะลดการทำงานของ server ได้ หนึ่งวิธีในนั้นที่ช่วยได้เยอะเลยคือการทำ cache
ใน Rails เองมีการทำ cache อยู่ 4 ระดับ คือ

  • page caching
  • action caching
  • fragment caching
  • sql caching

และตัวควบคุมการลบ cache พวกนี้ ก็คือ

  • sweeper

อันแรกนี้ ขอเป็น page caching ก่อน

ซึ่ง page caching เนี่ย มันจะเก็บ output ไว้เป็น file โดย save ไว้เป็น html เลย โดยเก็บไว้ใน public/ ซึ่งสามารถเปลี่ยนที่เก็บได้ เดี๋ยวค่อยว่ากันอีกที เมื่อมันมี request มา มันจะวิ่งเข้าที่ file นี้แทน แทนที่จะวิ่งไปที่ controller แล้วก็ทำงานตามที่เราเขียนไว้

การทำ page caching นี้ เหมาะสำหรับอะไรที่มันอยู่นานๆ แล้วคงจะไม่เปลี่ยน เช่นระบบ blog ซึ่งปกติ จะไม่ค่อยแก้ไขอะไรเท่าไหร่ จะทำการลบ cache นี้ออก ก็ต่อเมื่อมีการ update หรือมีการเพิ่มข้อคิดเห็น(comment) เป็นต้น

เริ่มต้นด้วยการเปิด cache ก่อน โดยปกติ ถ้าเราทำงานใน development environment มันจะปิดระบบ cache ทั้งหมด แต่ถ้าสลับมาเป็น production environment มันจะทำการเปิด cache ทุกอย่าง ลองดูใน config/environments/production.rb

  1
config.action_controller.perform_caching = true

ไปตั้งค่าให้เป็น true ใน config/environments/development.rb มันก็จะไปเปิดตัวจัดการ cache ให้

สมมติว่าถ้าต้องการเปลี่ยน path ในการเก็บ cache ก็ใส่เพิ่มไปว่า

  1
config.action_controller.page_cache_directory = RAILS_ROOT + "/public/wherever/you/want/"

เวลาเข้าถึงก็ http://localhost:3000/wherever/you/want/file

วิธีเซ็ต page caching ก็ง่ายๆ เราใส่ไปใน controller ว่า

  1
  2
  3
  4
  5
  6
class PostsController < ApplicationController
  caches_page :show
  def show
    @post = Post.find params[:id]
  end
end

แค่นี้เอง

เวลาจะลบ cache สมมติว่าเราจะลบ หลังจากที่เรา update content ของเรา เราก็ใส่ใน controller ไปว่า

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
def update
  @post = Post.find params[:id]
  if @post.update_attributes params[:post]
    flash[:notice] = "Updated"
    expire_page :action => "show", :id => @post.id
    redirect_to :action => "index"
  else 
    render :action => "edit"
  end
end

expire_page จะไปทำการลบให้เองเลย สบายมากๆ (รออีกสักหน่อย เดี๋ยวจะเขียนเรือง sweeper มาจัดการตรงนี้ครับ)

แต่ก็ใช่ว่าจะไม่มีปัญหาเลย เพราะหลังจาก update เสร็จแล้ว เราควรที่จะแสดงข้อความอะไรบอกหน่อย ในที่นี้ผมใส่ไปใน flash[:notice] ปัญหามันคือ มันจะเก็บ cache ไว้ในขณะที่มีข้อความนี้อยู่บนหน้า เพราะมันจะเก็บตอนที่เราสั่ง redirect_to

วิธีซ่อมแบบไม่ลงแรงเลยคือ ใช้ plugin ที่ชื่อว่า Cacheable Flash

เอามาจาก นั่งเทียนเขียนข่าว#12 ครับ

โดยวิธีการมันก็ง่ายๆ ครับ คือเก็บข้อความไว้ใน cookie ก่อน แล้วก็ดึงมาแสดงผลด้วย javascript อีกที
แต่ผมไม่ค่อยชอบ น่าจะมีตรวจว่ามี flash หรือเปล่า ก็เลยลงมืองัดแงะปลุกปล้ำเสียหน่อยได้หน้าตาแบบนี้

  1
caches_page :show, :if => Proc.new{ |p| p.request.session.data["flash"].blank?}

คือ cache ถ้า flash message ว่าง
ดูเท่กว่าเยอะ

ปล. อาทิตย์หน้ามาต่อกับ action caching ครับ

ข้อมูลจาก rails api

1 comment | Filed Under: Ruby on Rails | Tags: page caching

codegent: we're hiring