פיתוח Background Service Worker לתוספי דפדפן

משימות רקע בתוספי דפדפן עלולות להיקטע בפתאומיות, לאבד נתונים ולשבור לוגיקה. אנו מפתחים Background Service Workers עבור Manifest V3, ומבטיחים טיפול נכון באירועים ושמירת מצב. הצוות שלנו מספק פרויקטים סוהר—מבדיקת ארכיטקטורה ועד יישום ותמיכה מתמשכת—כך שהתוסף שלך פועל בצורה אמינה וצפויה.

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

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

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

השירותים שאנו מציעים
מציג 1 מתוך 1כל 2062 השירותים
פיתוח Background Service Worker לתוספי דפדפן
בינוני
~2-3 ימים

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

שאלות נפוצות

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

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

פיתוח Background Service Worker להרחבות דפדפן

בעיה: Background Service Worker אינו רק שינוי שם

ב-Manifest V3, דף הרקע המוכר הפך ל-service worker. זה שובר תבניות שעבדו שנים: הדפדפן יכול להפסיק את ה-SW בכל רגע אם אין משימות פעילות. נתקלנו בזה בפועל כאשר לקוח איבד נתונים עקב מונה גלובלי שלא שרד אתחול מחדש. הפתרון הוא לחשוב מחדש על הארכיטקטורה.

לדוגמה, בעת עיבוד הודעות נכנסות מ-content script, אם ה-handler לא נרשם באופן סינכרוני, אירועים עלולים ללכת לאיבוד. זה קורה כאשר מפתחים משתמשים באתחול אסינכרוני ברמה העליונה — הדפדפן פשוט לא "יראה" את ה-handler בהפעלה הראשונה של ה-SW. כתוצאה מכך, ההרחבה מפסיקה להגיב לפעולות משתמש.

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

מדוע ה-Service Worker מופסק?

הדפדפן מפעיל את ה-SW כאשר:

  • ההרחבה מותקנת/מתעדכנת
  • מתקבלת הודעה מ-content script או מ-popup
  • מופעל alarm
  • מתרחש אירוע רשת (אם נרשמתם אליו)

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

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

// ПЛОХО — состояние потеряется при перезапуске SW
let requestCount = 0;
chrome.runtime.onMessage.addListener(() => {
  requestCount++; // после перезапуска SW снова 0
});

// ХОРОШО — сохраняем в chrome.storage
chrome.runtime.onMessage.addListener(async () => {
  const { requestCount = 0 } = await chrome.storage.local.get('requestCount');
  await chrome.storage.local.set({ requestCount: requestCount + 1 });
});

כיצד להבטיח שמירת נתונים?

כלל ראשון: אל תסתמכו על משתנים גלובליים. השתמשו ב-// ПЛОХО — состояние потеряется при перезапуске SW let requestCount = 0; chrome.runtime.onMessage.addListener(() => { requestCount++; // после перезапуска SW снова 0 }); // ХОРОШО — сохраняем в chrome.storage chrome.runtime.onMessage.addListener(async () => { const { requestCount = 0 } = await chrome.storage.local.get('requestCount'); await chrome.storage.local.set({ requestCount: requestCount + 1 }); }); או ב-chrome.storage.local לאחסון מצב. שנית, עבור פעולות שחייבות להיות אטומיות, יש ליישם גישה טרנזקציונית עם תור. זה מבטיח שאף משימה לא תלך לאיבוד גם עם הפסקה פתאומית של ה-SW.

מדוע רישום אירועים סינכרוני חשוב?

יש לרשום handlers באופן סינכרוני ברמה העליונה. אחרת, הדפדפן עלול לא "לראות" אותם בעת הפעלת ה-SW:

// background/sw.js
// ПРАВИЛЬНО — синхронная регистрация
chrome.runtime.onInstalled.addListener(onInstalled);
chrome.runtime.onMessage.addListener(onMessage);
chrome.alarms.onAlarm.addListener(onAlarm);

async function onInstalled(details) {
  if (details.reason === 'install') {
    await chrome.storage.sync.set({ settings: defaultSettings });
  }
  if (details.reason === 'update') {
    await migrateSettings(details.previousVersion);
  }
}

function onMessage(message, sender, sendResponse) {
  handleMessage(message, sender).then(sendResponse);
  return true; // для async-ответов
}

השוואה בין MV2 ל-MV3: ביצועים ויציבות

קריטריון MV2 (רקע קבוע) MV3 (service worker)
מחזור חיים תהליך קבוע מופסק במצב סרק
מצב גלובלי עובד מתאפס באתחול מחדש
setTimeout/setInterval אמין לא אמין (השתמשו ב-alarms)
צריכת זיכרון תמיד פעיל רק בעת הצורך
מהירות טעינה גבוהה יותר נמוכה יותר (הפעלה עצלה)

MV3 מפחית את צריכת הזיכרון פי 2 בהשוואה ל-MV2, ואת זמן ההפעלה של ההרחבה ב-30% הודות לטעינה עצלה. החיסכון בתשתית השרת יכול להגיע ל-40%.

חיבורים ארוכי טווח באמצעות Port

למשימות שנמשכות יותר מכמה שניות (סטרימינג, polling), השתמשו ב-chrome.storage.sync. חיבור פעיל שומר על ה-SW בחיים:

chrome.runtime.onConnect.addListener((port) => {
  if (port.name !== 'streaming-channel') return;
  const controller = new AbortController();
  port.onDisconnect.addListener(() => controller.abort());
  streamData(port.sender.tab, controller.signal, (chunk) => {
    port.postMessage({ type: 'CHUNK', data: chunk });
  }).then(() => {
    port.postMessage({ type: 'DONE' });
  }).catch((err) => {
    if (err.name !== 'AbortError') {
      port.postMessage({ type: 'ERROR', message: err.message });
    }
  });
});

שימוש ב-chrome.alarms למשימות תקופתיות

// background/sw.js // ПРАВИЛЬНО — синхронная регистрация chrome.runtime.onInstalled.addListener(onInstalled); chrome.runtime.onMessage.addListener(onMessage); chrome.alarms.onAlarm.addListener(onAlarm); async function onInstalled(details) { if (details.reason === 'install') { await chrome.storage.sync.set({ settings: defaultSettings }); } if (details.reason === 'update') { await migrateSettings(details.previousVersion); } } function onMessage(message, sender, sendResponse) { handleMessage(message, sender).then(sendResponse); return true; // для async-ответов } ו-chrome.runtime.connect() אינם אמינים — הם לא שורדים אתחול מחדש. השתמשו ב-alarms:

chrome.runtime.onInstalled.addListener(() => {
  chrome.alarms.create('sync-data', { periodInMinutes: 15, delayInMinutes: 1 });
});

chrome.alarms.onAlarm.addListener(async (alarm) => {
  if (alarm.name === 'sync-data') {
    await syncWithServer();
  }
});

מידע נוסף על chrome.alarms בתיעוד הרשמי של Chrome.

טיפול בשגיאות ועמידות

ה-SW עלול להיהרג באמצע פעולה אסינכרונית. עבור פעולות קריטיות, השתמשו בגישה טרנזקציונית עם תור ב-chrome.storage:

async function processQueue() {
    const { queue = [] } = await chrome.storage.local.get('queue');
    if (queue.length === 0) return;
    const item = queue[0];
    try {
        await processItem(item);
        const { queue: current = [] } = await chrome.storage.local.get('queue');
        await chrome.storage.local.set({ queue: current.slice(1) });
    } catch (err) {
        const { queue: current = [] } = await chrome.storage.local.get('queue');
        current[0] = { ...current[0], attempts: (current[0].attempts ?? 0) + 1, lastError: err.message };
        await chrome.storage.local.set({ queue: current });
    }
}

כיצד לנפות באגים ב-Service Worker: תוכנית שלב אחר שלב

  1. פתחו את chrome.runtime.onConnect.addListener((port) => { if (port.name !== 'streaming-channel') return; const controller = new AbortController(); port.onDisconnect.addListener(() => controller.abort()); streamData(port.sender.tab, controller.signal, (chunk) => { port.postMessage({ type: 'CHUNK', data: chunk }); }).then(() => { port.postMessage({ type: 'DONE' }); }).catch((err) => { if (err.name !== 'AbortError') { port.postMessage({ type: 'ERROR', message: err.message }); } }); }); ובדקו את מצב ה-SW.
  2. ודאו שאירועים נרשמים באופן סינכרוני (השתמשו ב-chrome.runtime.onInstalled.addListener(() => { chrome.alarms.create('sync-data', { periodInMinutes: 15, delayInMinutes: 1 }); }); chrome.alarms.onAlarm.addListener(async (alarm) => { if (alarm.name === 'sync-data') { await syncWithServer(); } }); ברמה העליונה).
  3. בדקו שכל ה-handlers (async function processQueue() { const { queue = [] } = await chrome.storage.local.get('queue'); if (queue.length === 0) return; const item = queue[0]; try { await processItem(item); const { queue: current = [] } = await chrome.storage.local.get('queue'); await chrome.storage.local.set({ queue: current.slice(1) }); } catch (err) { const { queue: current = [] } = await chrome.storage.local.get('queue'); current[0] = { ...current[0], attempts: (current[0].attempts ?? 0) + 1, lastError: err.message }; await chrome.storage.local.set({ queue: current }); } } , console.log, onInstalled) מופיעים ביומנים.
  4. בצעו אמולציה של אתחול מחדש של ה-SW באמצעות onMessage (קראו ל-onAlarm או טענו מחדש את ההרחבה).
  5. ודאו שהנתונים משוחזרים מ-chrome.storage לאחר אתחול מחדש.

מה תקבלו כתוצאה?

  • Service Worker עובד במלואו עם רישום אירועים נכון.
  • העברה מ-MV2 ל-MV3 ללא אובדן פונקציונליות.
  • אופטימיזציה של ביצועים: הפחתת צריכת זיכרון פי 2.
  • אחסון מצב אמין באמצעות chrome.storage ותורים.
  • תיעוד ארכיטקטורה והוראות תחזוקה.
  • הבטחת פעולה יציבה: אנחנו אחראים לתוצאה.

שלבי פיתוח עבור SW

שלב משך (הערכה)
ביקורת של ההרחבה הנוכחית 1–2 ימים
עיצוב ארכיטקטורה 2–3 ימים
פיתוח ובדיקות 5–10 ימים
תיעוד ובדיקות סופיות 1–2 ימים
תמיכה לאחר השקה בהסכמה

למה להפקיד בידינו את הפיתוח?

יש לנו שנים של ניסיון ביצירת הרחבות דפדפן — למעלה מ-5 שנים בשוק, עשרות פרויקטים מוצלחים. המהנדסים שלנו מוסמכים ומבינים לעומק את הניואנסים של Manifest V3 ו-Service Workers. אנחנו מבטיחים פעולה יציבה של ההרחבה שלכם גם בתרחישים מורכבים. הזמינו ביקורת של ההרחבה שלכם — נזהה אזורים בעייתיים ונציע תוכנית העברה. קבלו ייעוץ על ארכיטקטורת Service Worker מהמהנדסים שלנו.

צרו קשר להערכת הפרויקט שלכם.