אתה מוציא תקציב על באנרים פרסומיים, אבל ה-CTR שלהם לא מגיע ל-1%. הבעיה היא שכולם רואים את אותה ההצעה. אנחנו פותרים זאת עם באנרים חכמים: בלוקים דינמיים שמראים לכל משתמש בדיוק את המוצרים שהוא צפה בהם או שהאלגוריתם מחשיב כרלוונטיים. התוצאה היא עלייה של פי 2-3 ב-CTR וגידול של 15-30% בהמרות. עלות רכישת לקוח (CAC) יורדת גם היא ב-20-30% הודות למיקוד רלוונטי יותר. צור קשר לייעוץ הנדסי לקבלת הערכה ראשונית.
איך עוקבים אחרי צפיות
הפרסונליזציה מתחילה באיסוף נתונים. אנו משתמשים במחלקת JavaScript ViewHistoryTracker ששומרת היסטוריית צפיות ב-localStorage ומסנכרנת עם השרת עבור משתמשים מחוברים. זהו פתרון מינימלי-פולשני — אין צורך בבאנר עוגיות או בהסכמת GDPR עבור סשנים אנונימיים.
class ViewHistoryTracker {
private readonly KEY = 'view_history';
private readonly MAX_ITEMS = 50;
track(item: ViewedItem): void {
const history = this.get();
const filtered = history.filter(i => i.id !== item.id);
const updated = [
{ ...item, viewed_at: Date.now() },
...filtered,
].slice(0, this.MAX_ITEMS);
localStorage.setItem(this.KEY, JSON.stringify(updated));
this.syncToServer(item);
}
get(): ViewedItem[] {
try {
return JSON.parse(localStorage.getItem(this.KEY) ?? '[]');
} catch {
return [];
}
}
getRecent(count = 10): ViewedItem[] {
return this.get().slice(0, count);
}
private async syncToServer(item: ViewedItem): Promise<void> {
if (!getAuthToken()) return;
await fetch('/api/views', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(item),
});
}
} מה מספק סינון שיתופי
הצגת המוצרים האחרונים שנצפו בלבד נותנת CTR נמוך — המשתמש כבר ראה אותם. אנו משתמשים בדירוג עם משקלי קטגוריות ופופולריות, וכן בסינון שיתופי כדי לבנות מטריצת משתמש-פריט. צפיות אחרונות מקבלות משקל גבוה יותר, וכפילויות מוחרגות. גישה זו מעלה את ה-CTR פי 2-3 במדידות שלנו.
function rankItems(history: ViewedItem[], candidates: CatalogItem[]): CatalogItem[] {
const categoryWeights: Record<string, number> = {};
const viewedIds = new Set(history.map(i => i.id));
history.forEach((item, index) => {
const recencyWeight = 1 / (index + 1);
categoryWeights[item.category] = (categoryWeights[item.category] ?? 0) + recencyWeight;
});
return candidates
.filter(c => !viewedIds.has(c.id))
.map(candidate => ({
...candidate,
score: (categoryWeights[candidate.category] ?? 0) * (candidate.popularity ?? 1),
}))
.sort((a, b) => b.score - a.score)
.slice(0, 6);
}לפרויקטים גדולים (מ-10,000 מוצרים) אנו מעבירים את המנוע לשרת על PHP/Laravel עם מטריצת PostgreSQL. אנו שומרים במטמון המלצות ב-Redis — זמן תגובת ה-API נשאר מתחת ל-50 אלפיות השנייה.
מקרה בוחן: חנות איקומרס לאלקטרוניקה עם קטלוג של 5000 מוצרים. לאחר יישום הבאנר החכם, ה-CTR גדל מ-0.8% ל-2.4%, ההמרה מבאנר לרכישה הייתה 12%. ערך ההזמנה הממוצע עלה ב-8% הודות למכירות צולבות.
השוואת גישות יישום
| פרמטר | מעקב בצד הלקוח + מנוע שרת | פלטפורמה חיצונית (Retail Rocket) |
|---|---|---|
| זמן יישום | 3–5 ימים | 1–2 ימים |
| דיוק ההמלצות | גבוה (אלגוריתמים עצמיים) | גבוה (מודלי ML) |
| עלות תחזוקה | נמוכה (שרת עצמי) | מנוי חודשי |
| שליטה בנתונים | מלאה | חלקית (העברת נתונים) |
| מדרגיות | עד 100,000 מוצרים | מ-10,000 עד 1M+ מוצרים |
השוואת אלגוריתמי המלצה
| קריטריון | דירוג בצד הלקוח | סינון שיתופי בצד השרת |
|---|---|---|
| נתונים | היסטוריה ב-localStorage | מטריצת רכישות וצפיות |
| דיוק | בינוני | גבוה |
| עומס על השרת | אין | בינוני (עם מטמון) |
| התחלה קרה | לא מהווה בעיה | דורש נתונים |
טעויות נפוצות במהלך היישום
- הצגת מוצרים שהמשתמש ראה זה עתה. תמיד יש להחריג פריטים שנצפו.
- התעלמות מפופולריות מוצרים — משקל קטגוריה ללא פופולריות נותן המלצות חלשות.
- אי שמירה במטמון של בקשות שרת. ללא Redis, כל צפייה יוצרת שאילתת SQL — עם 10,000 משתמשים מסד הנתונים יקרוס.
- אי מעקב אחר קליקים על הבאנר. ללא אנליטיקה, לא תדע את ה-CTR האמיתי.
- שכחת התאמה למובייל — הבאנר חייב להופיע כראוי בכל המכשירים.
איך אנו מיישמים רינדור באנר חכם
רכיב React (או Vue) מוטמע במיקום הרצוי: סרגל צד, בתוך תוכן או תחתון-דביק. הוא מבקש המלצות דרך API ומציג מוצרים עם תמונה, שם ומחיר. בעת לחיצה, נשלח אירוע ל-Google Analytics.
interface SmartBannerProps {
placement: 'sidebar' | 'inline' | 'sticky-bottom';
title?: string;
}
function SmartBanner({ placement, title = 'Вы смотрели' }: SmartBannerProps) {
const [items, setItems] = useState<CatalogItem[]>([]);
const [loading, setLoading] = useState(true);
useEffect(() => {
const history = tracker.getRecent();
if (history.length === 0) {
setLoading(false);
return;
}
fetch('/api/recommendations', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
viewed_ids: history.map(i => i.id),
categories: [...new Set(history.map(i => i.category))],
limit: placement === 'sidebar' ? 4 : 6,
}),
})
.then(r => r.json())
.then(data => setItems(data.items))
.finally(() => setLoading(false));
}, [placement]);
if (loading) return <BannerSkeleton count={4} />;
if (items.length === 0) return null;
return (
<div className={`smart-banner smart-banner--${placement}`}>
<h3 className="smart-banner__title">{title}</h3>
<div className="smart-banner__grid">
{items.map(item => (
<a
key={item.id}
href={item.url}
className="smart-banner__item"
onClick={() => trackBannerClick(item, placement)}
>
<img src={item.image} alt={item.title} loading="lazy" />
<span className="smart-banner__name">{item.title}</span>
<span className="smart-banner__price">{formatPrice(item.price)}</span>
</a>
))}
</div>
</div>
);
}
function trackBannerClick(item: CatalogItem, placement: string): void {
gtag('event', 'smart_banner_click', {
item_id: item.id,
item_name: item.title,
placement,
item_category: item.category,
});
} נקודת קצה לשרת להמלצות
אנו משתמשים ב-controller של Laravel שמחריג מוצרים שנצפו ומדרג לפי קטגוריה ופופולריות. למהירות אנו מוסיפים מטמון Redis.
class RecommendationsController extends Controller
{
public function index(Request $request): JsonResponse
{
$viewedIds = $request->input('viewed_ids', []);
$categories = $request->input('categories', []);
$limit = min($request->input('limit', 6), 12);
$items = Product::query()
->whereNotIn('id', $viewedIds)
->where('is_active', true)
->where(function ($q) use ($categories) {
$q->whereIn('category_slug', $categories)
->orWhere('is_bestseller', true);
})
->orderByRaw(
' CASE WHEN category_slug = ANY(?) THEN 1 ELSE 2 END, popularity DESC ',
['{' . implode(',', $categories) . '}']
)
->limit($limit)
->get(['id', 'title', 'price', 'image', 'url', 'category_slug']);
return response()->json(['items' => $items]);
}
} מתי לחבר פלטפורמות חיצוניות
לחנויות עם קטלוג מ-10,000 מוצרים או כשנדרש מודל ML מוכן, אנו משלבים Retail Rocket או Mindbox. אינטגרציית Retail Rocket בסיסית אורכת 1-2 ימים:
rrApi.view(123456);
rrApi.addToBasket(123456);
rrApiOnReady(function() {
rrApi.recommend('block_id_from_rr_panel', {
callback: function(items) {
renderRecommendations(items);
}
});
}); מה כלול
- תכנון סכמת מעקב ואחסון נתונים
- פיתוח רכיב באנר בצד הלקוח עם תמיכה במיקומים שונים
- נקודת קצה לשרת להמלצות עם מטמון
- אינטגרציית אנליטיקה (GA/Yandex.Metrica)
- תיעוד API והוראות הטמעה
- העברת מאגר הקוד וגישת אירוח
- הכשרת המפתח שלך (שעה מקוונת)
- אחריות ל-3 חודשים על פעילות תקינה של האלגוריתם
לוח זמנים ומחיר
לוח זמנים ליישום: מ-3 עד 8 ימים תלוי במורכבות. המחיר מחושב באופן אישי — אנו נעריך את הפרויקט לאחר שיחת היכרות. במהלך עבודתנו, יישמנו באנרים חכמים לעשרות חנויות איקומרס, עם עלייה ממוצעת של 180% ב-CTR. לצוות שלנו ניסיון של 5+ שנים בפרסונליזציה לאיקומרס.
אם אתה רוצה להגדיל המרות מבלוקים פרסומיים ללא עלות נוספת, צור קשר — נדון במשימה שלך ונציע את הפתרון הטוב ביותר. קבל ייעוץ הנדסי להערכה ראשונית.







