แสดงบทความที่มีป้ายกำกับ SWR แสดงบทความทั้งหมด
แสดงบทความที่มีป้ายกำกับ SWR แสดงบทความทั้งหมด

วันพุธที่ 5 มีนาคม พ.ศ. 2568

การแคชข้อมูลใน Next.js: โหลดเร็ว ประหยัดทรัพยากร ทำยังไง?

ถ้าอยากให้เว็บโหลดเร็ว แคช (Cache) คือสิ่งที่ต้องรู้! แคชช่วยลดการเรียก API ซ้ำ ๆ ประหยัดเวลา ประหยัดเซิร์ฟเวอร์ และทำให้ผู้ใช้รู้สึกว่าเว็บเร็วขึ้นมาก 🚀

ใน Next.js เรามีหลายวิธีในการแคชข้อมูล ตั้งแต่ Static Generation (SSG), Server-side Rendering (SSR), Client-side caching (SWR) ไปจนถึง Edge Caching วันนี้เราจะมาดูกันว่าแต่ละแบบใช้เมื่อไหร่ และทำให้เว็บเร็วขึ้นได้ยังไง!

🔥 ทำไมต้องแคชข้อมูล?

ลองนึกภาพว่าเว็บของคุณต้องโหลด สินค้าล่าสุด จาก API ทุกครั้งที่มีคนเข้าเว็บ … 🤯

  • ถ้าคนเข้า 100 คน = API ถูกเรียก 100 ครั้ง
  • ถ้า API ช้า? เว็บช้าไปด้วย
  • ถ้า API มีค่าใช้จ่าย? ยิ่งแพงขึ้นเรื่อย ๆ

แต่ถ้าเราสามารถเก็บข้อมูลไว้ชั่วคราว ไม่ต้องเรียก API ตลอดเวลา เว็บจะเร็วขึ้น ประหยัดทรัพยากร และลดโหลดเซิร์ฟเวอร์

🛠 วิธีการแคชใน Next.js

Next.js รองรับการแคชหลายแบบขึ้นอยู่กับว่า ข้อมูลของคุณเปลี่ยนบ่อยแค่ไหน

วิธีแคช ใช้เมื่อ ตัวอย่าง
Static Generation (SSG) ข้อมูลไม่ค่อยเปลี่ยน หน้า About, รายการสินค้า
Incremental Static Regeneration (ISR) ข้อมูลเปลี่ยนเป็นช่วง ๆ บทความข่าว, ราคา Bitcoin
Server-side Rendering (SSR) ข้อมูลต้องสดใหม่ทุกครั้ง ข้อมูลผู้ใช้, หน้าแดชบอร์ด
Client-side Fetching (SWR, React Query) ข้อมูลเปลี่ยนบ่อยแบบเรียลไทม์ Notification, Dashboard
Edge Caching ต้องการโหลดเร็วสุด ๆ Content ที่แจกจ่ายไปทั่วโลก (CDN)


🏗 1. แคชข้อมูลด้วย Static Generation (SSG)

ถ้าข้อมูลไม่เปลี่ยนบ่อย SSG เป็นวิธีที่ดีที่สุด เพราะ Next.js จะ ดึงข้อมูลมาตอน Build แล้วเสิร์ฟเป็นไฟล์ HTML ทำให้โหลดเร็วสุด ๆ

🔹 ตัวอย่าง SSG

export async function getStaticProps() {
  const res = await fetch('https://api.example.com/products')
  const products = await res.json()

  return { props: { products } }
}

export default function ProductsPage({ products }) {
  return (
    <ul>
      {products.map((product) => (
        <li key={product.id}>{product.name}</li>
      ))}
    </ul>
  )
}

✅ ข้อดีของ SSG

  • โหลดเร็วมาก เพราะเป็นไฟล์ HTML ธรรมดา
  • ลดโหลดเซิร์ฟเวอร์
  • เหมาะกับข้อมูลที่ไม่เปลี่ยนบ่อย เช่น บทความ หรือ รายการสินค้า

❌ ข้อเสีย

  • ถ้าข้อมูลเปลี่ยน จะไม่อัปเดตจนกว่าจะ Build ใหม่


🔄 2. อัปเดต Static Page ด้วย ISR (Incremental Static Regeneration)

ถ้าอยากใช้ SSG แต่ให้ข้อมูลอัปเดตเป็นช่วง ๆ เราสามารถใช้ revalidate เพื่อให้ Next.js รีเฟรชข้อมูลอัตโนมัติ

🔹 ตัวอย่าง ISR (รีเฟรชข้อมูลทุก 60 วินาที)

export async function getStaticProps() {
  const res = await fetch('https://api.example.com/news')
  const news = await res.json()

  return { props: { news }, revalidate: 60 } // รีเฟรชทุก 60 วินาที
}

✅ ข้อดีของ ISR

  • โหลดเร็วเหมือน SSG
  • ข้อมูลอัปเดตได้เอง ไม่ต้อง Deploy ใหม่


⚡ 3. โหลดข้อมูลฝั่งเซิร์ฟเวอร์ (SSR)

ถ้าข้อมูลต้องอัปเดตทุกครั้งที่มีคนเข้าหน้า SSR (Server-side Rendering) คือทางเลือกที่ดี

🔹 ตัวอย่าง SSR

export async function getServerSideProps() {
  const res = await fetch('https://api.example.com/user')
  const user = await res.json()

  return { props: { user } }
}

✅ ข้อดีของ SSR

  • ข้อมูลสดใหม่เสมอ
  • เหมาะกับข้อมูลผู้ใช้ หรือแดชบอร์ด

❌ ข้อเสีย

  • ช้ากว่า SSG และ ISR เพราะต้องรอโหลดทุกครั้ง


🌀 4. แคชข้อมูลฝั่ง Client ด้วย SWR

ถ้าต้องการให้ข้อมูล อัปเดตอัตโนมัติแบบเรียลไทม์ ใช้ SWR (Stale-While-Revalidate) เป็นตัวเลือกที่ดี

🔹 ตัวอย่างการใช้ SWR

import useSWR from 'swr'

const fetcher = (url) => fetch(url).then(res => res.json())

export default function Dashboard() {
  const { data, error } = useSWR('/api/dashboard', fetcher, { refreshInterval: 5000 })

  if (error) return <p>เกิดข้อผิดพลาด</p>
  if (!data) return <p>กำลังโหลด...</p>

  return <div>จำนวนผู้ใช้ตอนนี้: {data.users}</div>
}

✅ ข้อดีของ SWR

  • โหลดเร็วเพราะดึงจากแคชก่อน
  • อัปเดตข้อมูลอัตโนมัติ

❌ ข้อเสีย

  • ใช้ได้เฉพาะฝั่ง Client


🌍 5. ใช้ Edge Caching เพื่อโหลดเร็วสุด ๆ

ถ้าอยากให้ Response ถูกแคชทั่วโลก (CDN) Next.js มีฟีเจอร์ Middleware + Edge Functions

🔹 ตัวอย่าง Middleware Caching

import { NextResponse } from 'next/server'

export function middleware(req) {
  const response = NextResponse.next()
  response.headers.set('Cache-Control', 's-maxage=60, stale-while-revalidate')
  return response
}

✅ เหมาะกับ

  •     โหลดเร็วสุด ๆ สำหรับ Static Content
  •     ใช้ร่วมกับ CDN เช่น Vercel, Cloudflare


🔥 สรุป: ควรใช้แคชแบบไหน?

วิธีแคช ใช้เมื่อ
SSG ข้อมูลไม่เปลี่ยนบ่อย (โหลดเร็วมาก)
ISR ข้อมูลเปลี่ยนเป็นช่วง ๆ (อัปเดตอัตโนมัติ)
SSR ข้อมูลต้องสดใหม่ทุกครั้ง
SWR อัปเดตข้อมูลอัตโนมัติฝั่ง Client
Edge Caching โหลดเร็วสุด ๆ ทั่วโลก

✅ ใช้ SSG หรือ ISR ถ้าเป็นไปได้ เพราะเร็วและลดโหลดเซิร์ฟเวอร์
✅ ใช้ SSR เมื่อข้อมูลต้องอัปเดตเสมอ
✅ ใช้ SWR ถ้าเป็นข้อมูลที่ต้องอัปเดตเรียลไทม์

วันจันทร์ที่ 3 มีนาคม พ.ศ. 2568

การเรียก API ภายใน Next.js อย่างมีประสิทธิภาพ

การเรียก API เป็นเรื่องที่ทุกเว็บแอปต้องทำ ไม่ว่าจะเป็นการดึงข้อมูลจาก Backend, Third-party APIs หรือแม้แต่ API ภายในแอปเอง แต่จะเรียกยังไงให้เร็ว แรง และไม่ทำให้เว็บช้า?

Next.js มีหลายวิธีในการเรียก API ไม่ว่าจะเป็น Server-side fetching, Client-side fetching, Static generation, หรือแม้แต่ ใช้ API Routes ภายในตัวเอง วันนี้เราจะมาเจาะลึกกันว่าควรเลือกใช้วิธีไหนในแต่ละสถานการณ์ เพื่อให้แอปของคุณทำงานเร็วที่สุด 🚀

🔍 วิธีเรียก API ใน Next.js

ใน Next.js เราสามารถเรียก API ได้หลัก ๆ 3 วิธี

  1. Client-side fetching → ใช้ fetch หรือ SWR ใน React Component
  2. Server-side fetching (SSR) → ใช้ getServerSideProps เพื่อโหลดข้อมูลตอนโหลดหน้า
  3. Static generation (SSG) → ใช้ getStaticProps โหลดข้อมูลล่วงหน้า

แต่ละวิธีมีข้อดีข้อเสียต่างกัน เดี๋ยวมาดูรายละเอียดกันเลย!

🎯 1. การเรียก API ฝั่ง Client (Client-side Fetching)

ถ้าข้อมูลที่เราต้องการโหลด ไม่จำเป็นต้องมาเร็วก่อนหน้าแสดงผล เช่น

  •     รายการโพสต์
  •     คอมเมนต์
  •     ข้อมูลที่อัปเดตแบบเรียลไทม์

การใช้ Client-side Fetching จะช่วยให้หน้าเว็บโหลดเร็วขึ้นเพราะมันจะดึงข้อมูลหลังจากโหลดหน้าเสร็จ

🔹 วิธีใช้ fetch กับ useEffect (พื้นฐาน)

import { useEffect, useState } from 'react'

export default function Posts() {
  const [posts, setPosts] = useState([])
  const [loading, setLoading] = useState(true)

  useEffect(() => {
    fetch('/api/posts')
      .then((res) => res.json())
      .then((data) => {
        setPosts(data)
        setLoading(false)
      })
  }, [])

  if (loading) return <p>กำลังโหลดโพสต์...</p>

  return (
    <ul>
      {posts.map((post) => (
        <li key={post.id}>{post.title}</li>
      ))}
    </ul>
  )
}

แต่ปัญหาของวิธีนี้คือ ทุกครั้งที่เข้าเพจ มันจะ fetch API ใหม่เสมอ ซึ่งอาจทำให้โหลดข้อมูลซ้ำ ๆ แบบไม่จำเป็น

🔹 วิธีใช้ SWR ให้โหลดเร็วขึ้น

ถ้าอยากให้ ดึงข้อมูลแล้วแคชไว้ ไม่ต้องโหลดใหม่ตลอด SWR เป็นตัวช่วยที่ดี

import useSWR from 'swr'

const fetcher = (url) => fetch(url).then((res) => res.json())

export default function Posts() {
  const { data, error } = useSWR('/api/posts', fetcher)

  if (error) return <p>เกิดข้อผิดพลาด</p>
  if (!data) return <p>กำลังโหลด...</p>

  return (
    <ul>
      {data.map((post) => (
        <li key={post.id}>{post.title}</li>
      ))}
    </ul>
  )
}

✅ SWR ดียังไง?

  •     แคชข้อมูลไว้ ไม่ต้องโหลดใหม่ทุกครั้ง
  •     อัปเดตข้อมูลอัตโนมัติเมื่อมีการเปลี่ยนแปลง
  •     โหลดเร็วขึ้นเพราะดึงจากแคชก่อน แล้วอัปเดตภายหลัง

ถ้าเป็น ข้อมูลที่ต้องอัปเดตบ่อย เช่น Dashboard หรือ Notifications ควรใช้ SWR จะดีที่สุด!

⚡️ 2. การเรียก API ฝั่งเซิร์ฟเวอร์ (SSR)

บางครั้งเราต้องโหลดข้อมูล ก่อนแสดงผลหน้าเว็บ เช่น

  • ข้อมูลผู้ใช้ที่ล็อกอิน
  • สินค้าในตะกร้า
  • รายการสั่งซื้อ

ในกรณีนี้ getServerSideProps เป็นทางเลือกที่ดี เพราะมันจะดึงข้อมูลบนเซิร์ฟเวอร์ก่อนแล้วส่งไปให้หน้าเว็บ

🔹 วิธีใช้ getServerSideProps

export async function getServerSideProps() {
  const res = await fetch('https://jsonplaceholder.typicode.com/posts')
  const data = await res.json()

  return { props: { posts: data } }
}

export default function Posts({ posts }) {
  return (
    <ul>
      {posts.map((post) => (
        <li key={post.id}>{post.title}</li>
      ))}
    </ul>
  )
}

✅ ข้อดีของ SSR

  • โหลดข้อมูลก่อนแสดงผล → ผู้ใช้เห็นข้อมูลทันที
  • เหมาะกับข้อมูลที่เปลี่ยนแปลงบ่อย เช่น ข้อมูลผู้ใช้
  • รองรับ SEO ดีกว่า Client-side Fetching

❌ ข้อเสีย

  • โหลดช้ากว่าเพราะต้องรอ API ตอบก่อนแสดงผล
  • ถ้า API ช้าจะทำให้หน้าเว็บช้าไปด้วย

ถ้าเป็น API ที่ต้องใช้ข้อมูลสดใหม่ทุกครั้ง เช่น ข้อมูลผู้ใช้ที่ล็อกอินอยู่ getServerSideProps คือทางเลือกที่ดี

🏎 3. โหลด API ล่วงหน้าด้วย Static Generation (SSG)

ถ้าข้อมูลที่เราต้องการ เปลี่ยนแปลงไม่บ่อย เช่น

  • บทความ
  • รายชื่อสินค้า
  • รายการหมวดหมู่

เราสามารถใช้ getStaticProps โหลดข้อมูลตอน Build เวลา Deploy แล้วหน้าเว็บจะโหลดเร็วมาก 🚀

🔹 วิธีใช้ getStaticProps

export async function getStaticProps() {
  const res = await fetch('https://jsonplaceholder.typicode.com/posts')
  const data = await res.json()

  return { props: { posts: data } }
}

export default function Posts({ posts }) {
  return (
    <ul>
      {posts.map((post) => (
        <li key={post.id}>{post.title}</li>
      ))}
    </ul>
  )
}

✅ ข้อดีของ SSG

  • โหลดเร็วมาก เพราะไม่ต้องรอ API ตอนเปิดหน้า
  • เหมาะกับหน้าเว็บที่ข้อมูลเปลี่ยนไม่บ่อย

❌ ข้อเสีย

  • ข้อมูลจะไม่อัปเดตจนกว่าจะ Build ใหม่

ถ้าต้องการให้ SSG รีเฟรชข้อมูลได้เอง สามารถใช้ revalidate เช่น

export async function getStaticProps() {
  const res = await fetch('https://jsonplaceholder.typicode.com/posts')
  const data = await res.json()

  return { props: { posts: data }, revalidate: 60 } // รีเฟรชทุก 60 วินาที
}

🔥 สรุป: ควรใช้วิธีไหน?

วิธี ใช้เมื่อ ข้อดี ข้อเสีย
Client-side Fetching ข้อมูลเปลี่ยนบ่อย (Dashboard, คอมเมนต์) โหลดเร็ว ไม่ต้องรอ API ไม่ดีต่อ SEO
Server-side Fetching (SSR) ข้อมูลต้องอัปเดตทุกครั้ง เช่น ผู้ใช้ล็อกอิน โหลดก่อนแสดงผล ดีต่อ SEO ช้ากว่า Client-side
Static Generation (SSG) ข้อมูลเปลี่ยนไม่บ่อย เช่น บทความ โหลดเร็วมาก ไม่อัปเดตอัตโนมัติ

เลือกให้เหมาะสมกับโปรเจกต์ของคุณ แล้วเว็บจะทั้งเร็วและมีประสิทธิภาพ! 🚀

การใช้ Image Optimization ใน Next.js: โหลดไว SEO ดี ประหยัดแบนด์วิธ!

เคยเจอปัญหาเว็บโหลดช้าเพราะรูปภาพขนาดใหญ่หรือเปล่า? 📷 ถ้าใช่ Next.js มีฟีเจอร์ Image Optimization ที่ช่วยให้รูปภาพโหลดเร็วขึ้น อัตโนมัติ ไม...