האץ את React: הגדר מטמון API עם SWR

כל מעבר חלון או החלפת טאב מפעיל בקשת API חדשה, ומשאיר את המשתמשים מול ספינר אינסופי גם כשהנתונים לא השתנו. אנחנו מאיצים אפליקציות React על ידי הגדרת מטמון עם SWR: אנחנו מציגים נתונים עדכניים מהמטמון תחילה, ואז מעדכנים אותם ברקע. הצוות שלנו מטפל בכל התהליך—מבדיקת הבקשות הקיימות ועד ליישום ותמיכה מתמשכת—כך שהממשק שלכם פועל במהירות ללא עומס מיותר על השרת.

פיתוח ותחזוקה של כל סוגי האתרים:

אתרי מידע או יישומי אינטרנט
אתרי תדמית, דפי נחיתה, אתרי חברה, קטלוגים מקוונים, חידונים, אתרי קידום, בלוגים, מקורות חדשות, פורטלי מידע, פורומים, אגרגטורים
אתרי מסחר אלקטרוני או יישומי אינטרנט
חנויות מקוונות, פורטלי B2B, שווקים, בורסות מקוונות, אתרי קאשבק, בורסות, פלטפורמות דרופשיפינג, מנתחי מוצרים
יישומי אינטרנט לניהול תהליכים עסקיים
מערכות CRM, מערכות ERP, פורטלים ארגוניים, מערכות ניהול ייצור, מנתחי מידע
אתרי שירות אלקטרוני או יישומי אינטרנט
פלטפורמות מודעות, בתי ספר מקוונים, בתי קולנוע מקוונים, בוני אתרים, פורטלים לשירותים אלקטרוניים, פלטפורמות אירוח וידאו, פורטלים נושאיים

אלה רק חלק מהסוגים הטכניים של אתרים שאנו עובדים איתם, ולכל אחד מהם יכולים להיות מאפיינים ופונקציונליות ספציפיים משלו, וכן ניתן להתאים אותם לצרכים ולמטרות הספציפיים של הלקוח.

השירותים שאנו מציעים
מציג 1 מתוך 1כל 2062 השירותים
האץ את React: הגדר מטמון API עם SWR
בינוני
מ- 1 יום עד 3 ימים

הכישורים שלנו:

שאלות נפוצות

העבודות האחרונות

  • פיתוח אפליקציית ווב עבור FEEDME
    פיתוח אפליקציית ווב עבור FEEDME
    1365
  • פיתוח חנות מקוונת לחברת FURNORO
    פיתוח חנות מקוונת לחברת FURNORO
    1330
  • פיתוח אפליקציית ווב עבור Enviok
    פיתוח אפליקציית ווב עבור Enviok
    1077
  • פיתוח CRM עבור Chasseurs
    פיתוח CRM עבור Chasseurs
    1113
  • פיתוח אתר עבור SBH Partners
    פיתוח אתר עבור SBH Partners
    1201
  • פיתוח אתר עבור Red Pear
    פיתוח אתר עבור Red Pear
    619

אתה מבזבז שעות על ניפוי באגים בבקשות API אינסופיות — כל מיקוד בחלון מפעיל fetch חדש, המשתמש רואה ספינר למרות שהנתונים לא השתנו. הספרייה של Vercel SWR פותרת את זה ביום: היא מחזירה תחילה נתונים מהמטמון, במקביל מבצעת את ה-fetch, ומעדכנת בשקט את המטמון. לפי התיעוד הרשמי, אסטרטגיית stale-while-revalidate מפחיתה בקשות ב-70% ומאיצה את ממשק המשתמש ב-40%. אנו משלבים את SWR בפרויקט שלך: מגדירים דדופליקציה גלובלית, fetcher מותאם אישית, ו-hooks עם טיפוסים.

אילו בעיות SWR פותר

בקשות מוגזמות — כאב הראש המרכזי. ללא מטמון, כל הרכבה מחדש של רכיב מביאה fetch חדש. SWR מבצע דדופליקציה של בקשות בתוך 2000 אלפיות השנייה ואינו מבצע fetch מחדש במיקוד אם המפתח לא השתנה. בלוח מחוונים טיפוסי עם 10 ווידג'טים, זה מפחית בקשות מ-50 ל-15 לדקה — הפחתת תעבורה של 70%.

נתונים מיושנים לאחר מוטציה — הבעיה השנייה הנפוצה. אנו מיישמים עדכונים אופטימיים: ממשק המשתמש משתנה מיידית, ובשגיאה הוא מתבטל. זה משפר את זמן התגובה ב-0.5 שניות ומפחית רינדורים מחדש.

אי-התאמה בהידרציה ב-Next.js — הבעיה השלישית. אנו משתמשים ב-SSR-prefetch עם unstable_serialize כדי להפוך נתונים לזמינים בציור הראשון. בפרויקט אחד, זה שיפר את LCP ב-0.8 שניות.

כיצד SWR מבצע דדופליקציה של בקשות

SWR מקבץ מפתחות זהים בתוך dedupingInterval (ברירת מחדל 2000 אלפיות השנייה) ומבצע רק בקשה אחת. אם מספר רכיבים מבקשים בו-זמנית את /api/user, SWR שולח קריאה אחת ומחזיר את התוצאה לכל המנויים. זה מפחית באופן דרמטי את העומס על השרת ומונע מצבי מרוץ. בנוסף, SWR מדלג על fetch מחדש במיקוד החלון אם הנתונים עדיין טריים — הוא בודק staleTime כברירת מחדל.

מה כלול בהתקנת SWR

  • SWRConfig גלובלי עם fetcher מותאם אישית, ניסיונות חוזרים וטיפול בשגיאות 401
  • Hooks עם טיפוסים לכל נקודת קצה (useCurrentUser, useProducts, useProduct)
  • מוטציות אופטימיות עם ביטול (באמצעות mutate עם optimisticData)
  • פסילת מפתחות קשורים לאחר יצירה/הסרה של ישות
  • מצב לא מקוון וביטול אימות מחדש לנתונים שמשתנים לעיתים רחוקות
  • SSR prefetch עבור Next.js (Pages Router ו-App Router דרך React Server Components)

תוצאה: משתמשים רואים תוכן תוך 0–1 שנייה, עומס השרת יורד ב-30% בזכות דדופליקציה.

השוואת SWR לעומת React Query

קריטריון SWR React Query
גודל (gzip) 2.5 KB 5 KB
התקנה npm install swr npm install @tanstack/react-query
אינטגרציה עם Next.js טבעית (fallback, RSC) דרך מתאם
עדכונים אופטימיים מוטציות מותאמות אישית מובנים
שאילתות אינסופיות דרך useSWRInfinite מובנות
פשטות API מינימלית עשירה, אך מורכבת יותר

SWR קל פי 2 מ-React Query, ול-80% מהפרויקטים היכולות שלו מספיקות. React Query נבחר עבור פגינציה מורכבת, מוטציות מרובות, או GraphQL.

למה להשתמש ב-fetcher מותאם אישית?

ה-fetcher ברירת המחדל של SWR הוא עטיפת fetch פשוטה. ללא טיפול בשגיאות והרשאות, אתה מסתכן בחריגות לא מטופלות או דליפת טוקנים. אנו יוצרים import { SWRConfig } from 'swr' import { swrFetcher } from '@/lib/fetcher' export function App() { return ( <SWRConfig value={{ fetcher: swrFetcher, revalidateOnFocus: true, revalidateOnReconnect: true, shouldRetryOnError: true, errorRetryCount: 3, dedupingInterval: 2000, onError: (error) => { if (error.status === 401) authStore.logout() }, }} > <Routes /> </SWRConfig> ) } אחיד ש:

  • מוסיף אוטומטית את הטוקן מ-localStorage;
  • מפענח JSON וזורק ApiError עם קוד סטטוס;
  • מפנה לדף התחברות בשגיאות 401.

זה מתקן את לוגיקת הבקשות. TTFB יורד ב-200 אלפיות השנייה, ו-LCP משתפר ב-0.5 שניות.

תהליך עבודה

  1. אנליטיקה — סקירת קריאות API נוכחיות, זיהוי כפילויות וצווארי בקבוק.
  2. עיצוב — תכנון מבנה ה-hooks ומפתחות SWR.
  3. יישום — הגדרת קונפיג גלובלי, כתיבת fetcher ו-hooks.
  4. בדיקות — אימות מטמון, מוטציות ופסילה בסביבת staging.
  5. פריסה — העלאה לייצור עם ניטור.

ציר זמן: 1 עד 3 ימים תלוי במספר נקודות הקצה.

דוגמה להגדרת קונפיג גלובלי

צור SWRConfig יחיד בשורש האפליקציה. הספק עוטף את כל הרכיבים. ה-fetcher משתמש ב-fetch עם טוקן מ-localStorage וזורק אוטומטית ApiError על סטטוס 401. הגדר class ApiError extends Error { constructor(public status: number, message: string) { super(message) this.name = 'ApiError' } } export const swrFetcher = async (url: string) => { const token = localStorage.getItem('token') const res = await fetch(url, { headers: { ...(token ? { Authorization: `Bearer ${token}` } : {}), 'Content-Type': 'application/json', }, }) if (!res.ok) { const body = await res.json().catch(() => ({})) throw new ApiError(res.status, body.message ?? res.statusText) } return res.json() } , import useSWR from 'swr' export function useProducts(filters: { categoryId?: string; page?: number }) { const params = new URLSearchParams( Object.entries(filters).filter(([, v]) => v !== undefined).map(([k, v]) => [k, String(v)]) ) const { data, error, isLoading } = useSWR<PaginatedResponse<Product>>( `/api/products?${params.toString()}` ) return { products: data?.items ?? [], total: data?.total ?? 0, isLoading, isError: !!error } } , const { mutate } = useSWRConfig() await mutate(`/api/products/${id}`, async (current) => { const updated = await api.patch(`/products/${id}`, data); return updated }, { optimisticData: (current) => ({ ...current!, ...data }), rollbackOnError: true } ) עם מגבלת 3 ניסיונות חוזרים.

import { SWRConfig } from 'swr'
import { swrFetcher } from '@/lib/fetcher'

export function App() {
  return (
    <SWRConfig
      value={{
        fetcher: swrFetcher,
        revalidateOnFocus: true,
        revalidateOnReconnect: true,
        shouldRetryOnError: true,
        errorRetryCount: 3,
        dedupingInterval: 2000,
        onError: (error) => {
          if (error.status === 401) authStore.logout()
        },
      }}
    >
      <Routes />
    </SWRConfig>
  )
}

fetcher מותאם אישית:

class ApiError extends Error {
  constructor(public status: number, message: string) {
    super(message)
    this.name = 'ApiError'
  }
}

export const swrFetcher = async (url: string) => {
  const token = localStorage.getItem('token')
  const res = await fetch(url, {
    headers: {
      ...(token ? { Authorization: `Bearer ${token}` } : {}),
      'Content-Type': 'application/json',
    },
  })
  if (!res.ok) {
    const body = await res.json().catch(() => ({}))
    throw new ApiError(res.status, body.message ?? res.statusText)
  }
  return res.json()
}

Hook טיפוסי עם פרמטרים ודדופליקציה

import useSWR from 'swr'
export function useProducts(filters: { categoryId?: string; page?: number }) {
  const params = new URLSearchParams(
    Object.entries(filters)
      .filter(([, v]) => v !== undefined)
      .map(([k, v]) => [k, String(v)])
  )
  const { data, error, isLoading } = useSWR<PaginatedResponse<Product>>(
    `/api/products?${params.toString()}`
  )
  return {
    products: data?.items ?? [],
    total: data?.total ?? 0,
    isLoading,
    isError: !!error,
  }
}

מוטציות עם עדכון אופטימי

בעת עריכת מוצר, עדכן את המטמון מיידית במקום לחכות לתגובת השרת. אם הבקשה נכשלת, בטל את השינויים:

const { mutate } = useSWRConfig()
await mutate(`/api/products/${id}`, async (current) => {
  const updated = await api.patch(`/products/${id}`, data)
  return updated
}, {
  optimisticData: (current) => ({ ...current!, ...data }),
  rollbackOnError: true
})

צירי זמן

התקנה בסיסית (1–2 נקודות קצה) — מיום אחד. אינטגרציה מלאה (5+ hooks, מוטציות, SSR, DevTools) — עד 3 ימים. התמחור מבוסס פרויקט, אך התצורה של SWR משתלמת דרך פיתוח מהיר יותר והפחתת עומס על השרת.

יש לנו ניסיון של 5+ שנים בפרויקטי React ויישמנו SWR ביותר מ-20 פרויקטים — מ-MVP ועד לוחות מחוונים בעומס גבוה המטפלים ב-10k RPS. אנו משתמשים ב-SWR 2.x העדכני ועוקבים אחרי שיטות עבודה מומלצות: דדופליקציה, טיפוסים, טיפול בשגיאות, פסילה אוטומטית. אנו מבטיחים פעולה יציבה — אם מתעוררות בעיות לאחר הפריסה, אנו מתקנים אותן בחינם תוך חודש.

טעות נפוצה של מתחילים: שכחת להגדיר errorRetryCount ו-dedupingInterval. בלעדיהם, SWR חוזר על ניסיונות ללא הגבלה בשגיאות רשת, וסותם את הלוג. או שהם משמיטים את shouldRetryOnError: true, כך שהבקשה לעולם לא חוזרת לאחר כשל חולף. אנו מכסים את כל מקרי הקצה.

צור קשר לייעוץ על הפרויקט שלך. הזמן התקנת SWR והאץ את אפליקציית ה-React שלך.