مدیریت به‌روزرسانی‌های کارگران خدماتی با فوریت

به‌طور پیش‌فرض، چرخه عمر سرویس‌کار مستلزم این است که وقتی یک سرویس‌کار به‌روز شده پیدا و نصب می‌شود ، تمام برگه‌های باز که سرویس‌کار فعلی کنترل می‌کند باید بسته شوند یا قبل از اینکه سرویس‌کار به‌روزرسانی شده فعال شود و کنترل را به دست بگیرد، باید ناوبری شوند.

در بسیاری از موارد، ممکن است خوب باشد که اجازه دهید این در زمان مقرر اتفاق بیفتد، اما در برخی موارد، ممکن است بخواهید به کاربر هشدار دهید که یک به‌روزرسانی در انتظار سرویس‌کار وجود دارد، و سپس فرآیند جابجایی به آن را خودکار کنید. خدمتکار جدید برای انجام این کار، باید کدی را در صفحه خود و سرویس کار خود اضافه کنید.

کدی که باید در صفحه خود قرار دهید

کد زیر در یک عنصر <script> درون خطی با استفاده از ماژول های جاوا اسکریپت وارد شده از یک نسخه میزبان CDN از workbox-window اجرا می شود. یک سرویس‌کار را با استفاده از workbox-window ثبت می‌کند و اگر سرویس‌گر در مرحله انتظار گیر کند، واکنش نشان می‌دهد. هنگامی که یک کارگر سرویس منتظر پیدا می شود، این کد به کاربر اطلاع می دهد که نسخه به روز شده سایت در دسترس است و از او می خواهد که دوباره بارگذاری کند.

<!-- This script tag uses JavaScript modules, so the proper `type` attribute value is required -->
<script type="module">
  // This code sample uses features introduced in Workbox v6.
  import {Workbox} from 'https://storage.googleapis.com/workbox-cdn/releases/6.4.1/workbox-window.prod.mjs';

  if ('serviceWorker' in navigator) {
    const wb = new Workbox('/sw.js');
    let registration;

    const showSkipWaitingPrompt = async (event) => {
      // Assuming the user accepted the update, set up a listener
      // that will reload the page as soon as the previously waiting
      // service worker has taken control.
      wb.addEventListener('controlling', () => {
        // At this point, reloading will ensure that the current
        // tab is loaded under the control of the new service worker.
        // Depending on your web app, you may want to auto-save or
        // persist transient state before triggering the reload.
        window.location.reload();
      });

      // When `event.wasWaitingBeforeRegister` is true, a previously
      // updated service worker is still waiting.
      // You may want to customize the UI prompt accordingly.

      // This code assumes your app has a promptForUpdate() method,
      // which returns true if the user wants to update.
      // Implementing this is app-specific; some examples are:
      // https://open-ui.org/components/alert.research or
      // https://open-ui.org/components/toast.research
      const updateAccepted = await promptForUpdate();

      if (updateAccepted) {
        wb.messageSkipWaiting();
      }
    };

    // Add an event listener to detect when the registered
    // service worker has installed but is waiting to activate.
    wb.addEventListener('waiting', (event) => {
      showSkipWaitingPrompt(event);
    });

    wb.register();
  }
</script>

اگر آنها قبول کنند، messageSkipWaiting() به کارگر سرویس منتظر می گوید که self.skipWaiting() را فراخوانی کند، به این معنی که شروع به فعال شدن می کند. پس از فعال شدن، سرویس‌کار جدید کنترل هر کلاینت موجود را در دست می‌گیرد و رویداد controlling را در workbox-window فعال می‌کند. هنگامی که این اتفاق می‌افتد، صفحه فعلی با استفاده از آخرین نسخه تمام دارایی‌های از پیش ذخیره‌شده و هر منطق مسیریابی جدیدی که در سرویس‌کار به‌روزرسانی یافت می‌شود، بارگیری مجدد می‌شود.

کدی که باید در سرویسکار خود قرار دهید

هنگامی که کد بخش قبلی را در صفحه خود دریافت کردید، باید کدی را به کارمند خدمات خود اضافه کنید تا بداند چه زمانی از مرحله انتظار رد شود. اگر از generateSW از workbox-build استفاده می‌کنید و گزینه skipWaiting آن را روی false (پیش‌فرض) تنظیم کرده‌اید، پس بهتر است ادامه دهید، زیرا کد زیر به‌طور خودکار در فایل سرویس‌کار تولید شده شما گنجانده می‌شود.

اگر در حال نوشتن سرویس کار خود هستید - شاید در ارتباط با یکی از ابزارهای ساخت Workbox در حالت injectManifest - باید کد زیر را خودتان اضافه کنید:

addEventListener('message', (event) => {
  if (event.data && event.data.type === 'SKIP_WAITING') {
    self.skipWaiting();
  }
});

این به پیام‌های ارسال شده به سرویس‌کار از workbox-window با مقدار type SKIP_WAITING گوش می‌دهد، و زمانی که این اتفاق افتاد، self.skipWaiting() را فراخوانی می‌کند. متد messageSkipWaiting() در workbox-window که در نمونه کد قبلی نشان داده شده است، مسئول ارسال این پیام است.

آیا نیاز به نشان دادن اعلان دارید؟

این الگویی نیست که هر برنامه کاربردی که یک کارگر خدماتی را مستقر می کند باید از آن پیروی کند. این برای سناریوهای انتخابی است که در آن ناتوانی در ارائه فرصتی برای بارگذاری مجدد صفحه در به‌روزرسانی کارگر سرویس ممکن است رفتارهای غیرمنتظره‌ای ایجاد کند. هیچ قانون سخت و سریعی برای نشان دادن اعلان بارگیری مجدد وجود ندارد، اما در اینجا چند موقعیت وجود دارد که ممکن است منطقی باشد:

  • شما به طور گسترده از precaching استفاده می کنید. در مورد دارایی‌های استاتیک، اگر از استراتژی شبکه اول یا فقط شبکه برای درخواست‌های ناوبری استفاده کنید، اما از دارایی‌های استاتیک با بار تنبلی استفاده کنید، می‌توانید بعداً با مشکل مواجه شوید. این می‌تواند موقعیت‌هایی را ایجاد کند که دارایی‌های نسخه‌سازی‌شده ممکن است تغییر کنند و یک سرویس‌دهنده آنها را از قبل ذخیره نکرده باشد. ارائه دکمه بارگذاری مجدد در اینجا ممکن است از برخی رفتارهای غیرمنتظره جلوگیری کند.
  • اگر از HTML پیش کش استفاده می کنید. در این مورد، باید به شدت در نظر داشته باشید که دکمه بارگذاری مجدد را برای به‌روزرسانی‌های Service Worker ارائه دهید، زیرا به‌روزرسانی‌های آن HTML تا زمانی که سرویس‌کار به‌روزرسانی کنترل را در دست نگیرد، شناسایی نخواهد شد.
  • اگر بیشتر به ذخیره سازی زمان اجرا متکی نیستید. هنگام ذخیره منابع در زمان اجرا، لازم نیست به کاربر اطلاع دهید که باید دوباره بارگذاری شود. همانطور که دارایی های نسخه شده تغییر می کنند، در زمان مناسب به حافظه پنهان زمان اجرا اضافه می شوند - با فرض اینکه درخواست های ناوبری از یک استراتژی شبکه اول یا فقط شبکه استفاده می کنند.
  • هنگام استفاده از استراتژی stale-while-veridate ، ممکن است استفاده از ماژول workbox-broadcast-update در نظر بگیرید تا کاربران را از به‌روزرسانی‌های Service Worker مطلع کنید.

اینکه آیا باید کاربر را از به‌روزرسانی‌ها به یک سرویس‌گر مطلع کنید، به برنامه شما و الزامات منحصر به فرد آن بستگی دارد. اگر متوجه می‌شوید که کاربران شما رفتارهای عجیب و غریبی را هنگام بیرون راندن یک سرویس‌دهنده جدید تجربه می‌کنند، این احتمالاً بهترین سیگنال شماست که باید به آنها اطلاع دهید.