เกิดอะไรขึ้น
เราเคยเข้าใจว่าพอ Server Component render เสร็จแล้ว ผลลัพธ์จะถูกใช้ซ้ำเมื่อผู้ใช้เปลี่ยนหน้าไปแล้วกลับมา เหมือนถูก cache ไว้ แต่พอกดลิงก์ในหน้าเว็บ บางหน้ากลับช้า และ log ฝั่ง server แสดงว่าการดึงข้อมูลรันใหม่ทุกครั้งที่เข้าหน้านั้น
ตอนแรกเราไล่หาบั๊กใน client ทั้งที่ต้นเหตุอยู่ที่ฝั่ง server
ทำไมถึงเป็นแบบนั้น
ผลลัพธ์ของ Server Component ไม่ใช่ cache ในตัวมันเอง เวลา soft navigation ฝั่ง client จะขอ RSC payload ของ route segment ใหม่จาก server และ server ก็ render ใหม่ layout ที่ใช้ร่วมกันระหว่างหน้าเก่ากับหน้าใหม่จะไม่ถูก render ซ้ำ แต่ segment ของ page จะถูก render
ส่วนที่ใช้ซ้ำได้ขึ้นกับเวอร์ชันและการตั้งค่า ใน Next.js 14 Router Cache ฝั่ง client เก็บหน้า dynamic ที่เคยเข้าไว้ 30 วินาที และ Data Cache ของ fetch() เปิดเป็นค่าเริ่มต้น ส่วน Next.js 15 เปลี่ยนค่าเริ่มต้น คือ fetch ไม่ถูก cache และ segment ของ page จะไม่ถูกใช้ซ้ำจาก Router Cache เว้นแต่ตั้ง staleTimes ดังนั้นอย่าสมมติพฤติกรรมเอาเอง
ตอนนี้เราทำอย่างไร
ตัดสินใจเป็นราย fetch ให้ชัด ข้อมูลที่เปลี่ยนไม่บ่อยให้ cache ไว้พร้อม tag แล้ว revalidate ด้วย revalidateTag ตอนข้อมูลเปลี่ยน ข้อมูลเฉพาะผู้ใช้ให้เป็น dynamic ต่อไป และถ้าหลาย component ใน render เดียวกันอ่านข้อมูลเดียวกัน ให้ใช้ React cache() ช่วยไม่ให้ดึงซ้ำ
เวลาทดสอบให้กดลิงก์เปลี่ยนหน้าจริง ๆ ไม่ใช่แค่ hard refresh เพราะสองแบบนี้เดินคนละเส้นทางของ cache
const res = await fetch('https://api.example.com/products', {
cache: 'force-cache',
next: { tags: ['products'] },
})
const products = await res.json()เช็กลิสต์สั้น ๆ
- 1เปิดหน้าที่ช้า แล้ว log ว่าแต่ละ Server Component ดึงอะไรบ้าง
- 2เช็กเวอร์ชัน Next.js เพราะค่าเริ่มต้นของ 14 กับ 15 ต่างกัน
- 3ตัดสินใจรายตัวว่า fetch ไหนต้องสดเสมอ, cache จนกว่าจะ revalidate tag หรือ cache เป็นช่วงเวลา
- 4ใช้ React cache() ลดการอ่านข้อมูลซ้ำใน render เดียวกัน
- 5ทดสอบด้วยการคลิกลิงก์ ไม่ใช่แค่ reload
จำไว้สั้น ๆ
อย่าสมมติว่าผลลัพธ์ของ Server Component ถูก cache ให้ตัดสินใจเรื่อง caching ของแต่ละ fetch ให้ชัดเจน