GORAGOD.com

บทที่ 12 AJAX กับ Cache ของ Browser

Cache เป็นเรื่องหนึ่งที่มีคนพูดถึงกันน้อยมาก ซึ่งเป็นเรื่องที่น่าปวดหัวมากสำหรับคนที่ใช้ AJAX ใหม่ๆ ในบางกรณี Cache อาจมีประโยชน์ แต่ในบางกรณี Cache อาจสร้างปัญหาให้ได้ ตัวอย่างปัญหาที่พบบ่อยๆคือ เวลาที่เราอัปเดทข้อมูลใหม่ลงฐานข้อมูลแล้ว แต่ AJAX กลับเรียกเอาข้อมูลเดิมมาแสดง แทนที่จะเอาข้อมูลใหม่มาแสดง ซึ่งปัญหานี้เราจะพบได้บน IE เป็นส่วนใหญ่ครับ

Cache เป็นคุณสมบัติหนึ่งของ AJAX (ผมไม่แน่ใจว่าเป็นคุณสมบัติ เฉพาะ IE หรือเปล่า) เพื่อลดการติดต่อกับ Server ครับ โดยที่เมื่อไรก็ตามที่เราเรียกใช้ AJAX มันก็จะไปตรวจสอบว่ามีการเรียกข้อมูลนี้มาก่อนหน้าหรือไม่ ถ้ามีการเรียกใช้มาแล้ว AJAX ก็จะไปเรียกเอาข้อมูลที่ถูกเรียกมาแล้ว (จาก Cache ของ IE ใน Temporary Internet Files) มาแสดงแทนโดยที่ไม่ต้องไปร้องขอเอาจาก Server ซึ่งก็จะทำให้ AJAX สามารถทำงานได้รวดเร็วขึ้นอีก

โดยทั่วๆไป AJAX ถูกกำหนดให้มีการเรียกใช้จาก Cache ได้ครับ แต่มันมีปัญหาน่ะสิครับ ลองดูตัวอย่างใน บทที่ 5 สิครับ ถ้านาฬิกา เรียกใช้ข้อมูลจาก Cache จะเกิดอะไรขึ้น คำตอบง่ายๆก็คือ เวลามันไม่เดิน น่ะสิครับ เพราะว่าเมื่อไรก็ตามที่เรียกใช้ AJAX มันก็ไปเรียกเอาข้อมูลเวลาเดิม ซึ่งก็คือเวลาข้อมูลก่อนหน้ามาแสดง ทั้งๆที่เวลาของ Server ก็เดินเรื่อยไป

แล้วเมื่อไรที่ AJAX เรียกใช้ข้อมูลจาก Cache บ้าง Browser ดูเอาจาก Query หรือ Link ทีเราส่งไปเรียกใช้ AJAX ครับ ถ้าเป็นลิงค์ที่เคยมีมาก่อนหน้า AJAX ก็จะไปเรียกเอาจาก Cache ครับ เช่น ถ้าครั้งแรกเราเรียก index.php?id=1 AJAX ก็จะไปเรียกข้อมูลครั้งแรกมาจาก Server แล้วก็เอาไปเก็บไว้ใน Cache ซึ่งก็เป็นขั้นตอนตามปกติของ Browser ครับ ครั้งที่ 2 ถ้าเรียก index.php?id=2 ในครั้งนี้ ถึงแม้จะเรียกไปที่หน้าเดิมแต่ Query มันเปลี่ยนไป AJAX ก็จะยังคงไปเรียกเอาจาก Server ครับ แต่ถ้าหากเรากลับไปเรียก index.php?id=1 อีกครั้งในครั้งที่ 3 ในครั้งนี้จะเห็นได้ว่า AJAX โหลดหน้านี้เร็วกว่าเดิมมาก ซึ่ง AJAX ได้ไปเรียกหน้านี้เอาจาก Cache ที่ถูกเรียกในครั้งแรกมาแสดงแทนนั่นเอง

การแก้ไขหรือการป้องกันไม่ให้ AJAX ไปเรียกข้อมูลจาก Cache ในกรณีที่เราต้องการให้ ข้อมูลถูก Update ทุกครั้งเมื่อเรียกใช้ AJAX เช่น นาฬิกาจาก Server หรือการแสดงข้อมูลที่ อัปเดทล่าสุด มี 2 วิธีครับ

1.เปลี่ยน Query ไปเรื่อยๆ ก็อย่างที่ผมบอกแต่แรก ว่า ถ้า Query มันเปลี่ยนไป มันก็จะไม่ไปเอาข้อมูลจาก Cache ดังนั้นถ้าเรากำหนดให้ Query มันไม่ซ้ำเดิมเราก็จะได้ข้อมูลใหม่ตลอดเวลา เช่น

โดยปกติเราจะใช้โค้ดนี้ในการ สร้าง connection กัน

req.open("GET", "index.php");

ให้เปลี่ยนมาเป็นใช้โค้ดนี้แทนครับ

req.open("GET", "index.php?"+ new Date().getTime() + Math.random() );

โค้ดที่เพิ่มขึ้นมาเป็นการ random ตัวเลข ส่งไปกับ query ซึ่งจะไม่ซ้ำกันในแต่ละครั้งที่เรียก ทำให้ query ไม่ซ้ำเดิมซึ่งก็จะให้ Browser เรียกเอาข้อมูลใหม่ทุกครั้ง

2.กำหนดให้ Browser ไม่ เรียกข้อมูลจาก Cache ด้วยการกำหนด header ครับ เหมือนที่ท่านเห็นในหลายๆตัวอย่างนั่นแหละครับ

<?
  //กำหนดให้ IE อ่าน page นี้ทุกครั้ง ไม่ไปเอาจาก cache
  header ("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
  header ("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
  header ("Cache-Control: no-cache, must-revalidate");
  header ("Pragma: no-cache");
?>

สำหรับในกรณีอื่นๆ ที่ Cache อาจมีประโยชน์ ก็ได้แก่ กรณีที่เราต้องเรียก AJAX เพื่ออ่านข้อมูลจากฐานข้อมูลซึ่งไม่ค่อยเปลี่ยนแปลงบ่อยนักมาแสดง อย่างเช่นการแสดงกระทู้ล่าสุดของเว็บบอร์ดบนเว็บนี้ ซึ่งข้อมูลจะต้องถูกตรวจสอบตลอดเวลา แต่เนื่องจากข้อมูลมันไม่มีการเปลี่ยนแปลงบ่อยนัก ทำให้การอ่านข้อมูลจากฐานข้อมูลทุกครั้งทีมีการเรียกใช้ไม่ค่อยจะมีประสิทธิ์ภาพนักเนื่องจากฐานข้อมูลจะทำงานหนักเกินไป ในกรณีเช่นนี้หากเราเลือกใช้ Cache ของ Browser หากมีการโพสต์เราก็จะไม่เห็นข้อมูลใหม่ หากเราไม่ใช้ Cache Server ก็จะทำงานหนัก วิธีแก้ไขในกรณีนี้ก็คือการเลือกใช้ Cache ของเราเองครับ ด้วยการยกเลิกการใช้ Cache ของ Browser แล้วสร้าง Cache ของเราเองโดยการที่เมื่อใดก็ตามที่มีการโพสต์หรือตอบข้อความ ให้มีการสร้างไฟล์ Cache ขึ้นทุกครั้ง (อาจสร้างเป็นไฟล์ XML หรือไฟล์อื่นใดที่แสดงผลได้ทันทีเพื่อลดการประมวลผลอีกครั้งก็ได้) แล้วเมื่อไรก็ตามที่มีการร้องขอข้อมูลก็ให้ไปเรียกเอาจาก Cache ที่สร้างไว้แทนการไปอ่านข้อมูลจากฐานข้อมูลครับ