tl;dr
از Chrome 68، درخواستهای HTTP که بهروزرسانیهای اسکریپت کارگر سرویس را بررسی میکنند، دیگر توسط حافظه پنهان HTTP بهطور پیشفرض برآورده نمیشوند. این کار حول یک نقطه درد مشترک توسعهدهنده کار میکند، که در آن تنظیم سرصفحه Cache-Control
غیرعمدی در اسکریپت Service Worker شما میتواند منجر به بهروزرسانیهای تاخیری شود.
اگر قبلاً از کش کردن HTTP برای اسکریپت /service-worker.js
خود با ارائه آن با Cache-Control: max-age=0
انصراف دادهاید، به دلیل رفتار پیشفرض جدید نباید هیچ تغییری را مشاهده کنید.
علاوه بر این، از Chrome 78، مقایسه بایت به بایت برای اسکریپت های بارگیری شده در یک سرویس دهنده از طریق importScripts()
اعمال خواهد شد. هر تغییری که در یک اسکریپت وارد شده ایجاد شود، جریان بهروزرسانی کارگر سرویس را راهاندازی میکند، درست مانند تغییر در سرویسکار سطح بالا.
پس زمینه
هر بار که به صفحه جدیدی هدایت میشوید که در محدوده یک سرویسکار قرار دارد، صریحاً registration.update()
را از جاوا اسکریپت فراخوانی کنید، یا زمانی که یک سرویسکار از طریق یک رویداد push
یا sync
"بیدار میشود"، مرورگر به طور موازی درخواست میکند. منبع جاوا اسکریپت که در ابتدا به فراخوانی navigator.serviceWorker.register()
ارسال شد تا بهروزرسانیهای اسکریپت کارگر سرویس را جستجو کند.
برای اهداف این مقاله، فرض کنید URL آن /service-worker.js
است و حاوی یک فراخوانی به importScripts()
است، که کد اضافی را که در داخل سرویسکار اجرا میشود بارگیری میکند:
// Inside our /service-worker.js file:
importScripts('path/to/import.js');
// Other top-level code goes here.
چه چیزی در حال تغییر است؟
قبل از Chrome 68، درخواست بهروزرسانی برای /service-worker.js
از طریق کش HTTP انجام میشد (همانطور که اکثر واکشیها هستند). این بدان معناست که اگر اسکریپت در ابتدا با Cache-Control: max-age=600
، بهروزرسانیها در 600 ثانیه (10 دقیقه) آینده به شبکه نمیرفت، بنابراین کاربر ممکن است بهروزترین نسخه را دریافت نکند. از کارگر خدماتی با این حال، اگر max-age
بیش از 86400 (24 ساعت) باشد، به عنوان 86400 رفتار می شود تا کاربران برای همیشه با یک نسخه خاص گیر نکنند.
از سال 68، حافظه پنهان HTTP هنگام درخواست بهروزرسانی اسکریپت Service Worker نادیده گرفته میشود، بنابراین برنامههای وب موجود ممکن است شاهد افزایش تعداد درخواستها برای اسکریپت Service Worker خود باشند. درخواستهای importScripts
همچنان از طریق کش HTTP ارسال میشوند. اما این فقط پیشفرض است—یک گزینه ثبتنام جدید، updateViaCache
در دسترس است که کنترل این رفتار را ارائه میدهد.
به روز رسانی ViaCache
توسعهدهندگان اکنون میتوانند هنگام فراخوانی navigator.serviceWorker.register()
گزینه جدیدی را ارسال کنند: پارامتر updateViaCache
. یکی از سه مقدار را می گیرد: 'imports'
، 'all'
یا 'none'
.
مقادیر تعیین میکنند که آیا و چگونه حافظه پنهان استاندارد HTTP مرورگر هنگام درخواست HTTP برای بررسی منابع بهروز شده سرویسدهنده، وارد عمل میشود.
وقتی روی
'imports'
تنظیم شود، حافظه پنهان HTTP هرگز هنگام بررسی بهروزرسانیهای اسکریپت/service-worker.js
مورد استفاده قرار نمیگیرد، اما هنگام واکشی اسکریپتهای وارد شده (در مثال ماpath/to/import.js
) از آن استفاده میشود. . این پیشفرض است و با رفتاری که در Chrome 68 شروع میشود مطابقت دارد.وقتی روی
'all'
تنظیم شود، هنگام درخواست برای اسکریپت سطح بالا/service-worker.js
و همچنین هر اسکریپت وارد شده در داخل سرویسکار، مانندpath/to/import.js
از حافظه پنهان HTTP استفاده میشود. . این گزینه با رفتار قبلی کروم، قبل از کروم 68 مطابقت دارد.وقتی روی
'none'
تنظیم شود، هنگام درخواست برای/service-worker.js
سطح بالا یا هر اسکریپت وارد شده، مانندpath/to/import.js
، از حافظه پنهان HTTP استفاده نمی شود.
برای مثال، کد زیر یک سرویسکار را ثبت میکند و اطمینان حاصل میکند که هنگام بررسی بهروزرسانیهای اسکریپت /service-worker.js
یا هر اسکریپتهایی که از طریق importScripts()
در داخل /service-worker.js
ارجاع داده میشوند، هرگز از حافظه پنهان HTTP استفاده نمیشود. /service-worker.js
:
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('/service-worker.js', {
updateViaCache: 'none',
// Optionally, set 'scope' here, if needed.
});
}
به روز رسانی اسکریپت های وارد شده را بررسی می کند
قبل از Chrome 78، هر اسکریپت service worker بارگیری شده از طریق importScripts()
فقط یک بار بازیابی میشد (بسته به پیکربندی updateViaCache
ابتدا با حافظه پنهان HTTP یا از طریق شبکه بررسی شود). پس از بازیابی اولیه، در داخل مرورگر ذخیره می شود و هرگز دوباره واکشی نمی شود.
تنها راه برای مجبور کردن یک سرویسکار از قبل نصبشده برای دریافت تغییرات در یک اسکریپت وارد شده، تغییر URL اسکریپت بود، معمولاً یا با افزودن یک مقدار semver (مثلا importScripts('https://example.com/v1.1.0/index.js')
) یا با اضافه کردن هش از محتویات (به عنوان مثال importScripts('https://example.com/index.abcd1234.js')
). یک اثر جانبی تغییر URL وارد شده این است که محتویات اسکریپت اسکریپت کارگر سطح بالا تغییر می کند، که به نوبه خود جریان به روز رسانی سرویس کار را آغاز می کند.
از Chrome 78 شروع میشود، هر بار که بررسی بهروزرسانی برای یک فایل سرویسدهنده سطح بالا انجام میشود، بررسیهایی همزمان انجام میشود تا مشخص شود آیا محتوای هر یک از اسکریپتهای وارد شده تغییر کرده است یا خیر. بسته به هدرهای Cache-Control
استفاده شده، اگر updateViaCache
روی 'all'
یا 'imports'
(که مقدار پیشفرض است) تنظیم شود، این بررسیهای اسکریپت وارد شده ممکن است توسط حافظه پنهان HTTP انجام شود، یا اگر بررسیها ممکن است مستقیماً در مقابل شبکه قرار گیرند. updateViaCache
روی 'none'
تنظیم شده است.
اگر بررسی بهروزرسانی برای یک اسکریپت وارد شده منجر به تفاوت بایت به بایت در مقایسه با آنچه قبلاً توسط سرویسکار ذخیره شده بود، منجر به جریان بهروزرسانی کامل سرویسکارگر شود، حتی اگر فایل سرویسکار سطح بالا باقی بماند. همان
رفتار کروم 78 با آنچه که فایرفاکس چندین سال پیش در فایرفاکس 56 پیاده سازی کرده بود مطابقت دارد. سافاری قبلاً این رفتار را نیز اجرا کرده است.
توسعه دهندگان چه کاری باید انجام دهند؟
اگر عملاً از کش کردن HTTP برای اسکریپت /service-worker.js
خود با ارائه آن با Cache-Control: max-age=0
(یا مقدار مشابه) انصراف داده اید، پس نباید هیچ تغییری را به دلیل رفتار پیش فرض جدید
اگر اسکریپت /service-worker.js
خود را با فعال کردن حافظه پنهان HTTP ارائه میکنید، عمداً یا به دلیل اینکه این اسکریپت پیشفرض برای محیط میزبانی شما است، ممکن است شاهد افزایش درخواستهای HTTP اضافی برای /service-worker.js
باشید که در مقابل شما ایجاد شده است. سرور—اینها درخواست هایی هستند که قبلاً توسط کش HTTP انجام می شد. اگر میخواهید به مقدار هدر Cache-Control
اجازه دهید تا بر تازگی /service-worker.js
شما تأثیر بگذارد، باید هنگام ثبت سرویسکار خود، به طور صریح updateViaCache: 'all'
را تنظیم کنید.
با توجه به اینکه ممکن است تعداد زیادی از کاربران در نسخه های قدیمی مرورگر وجود داشته باشند، همچنان ایده خوبی است که به تنظیم Cache-Control: max-age=0
هدر HTTP در اسکریپت های سرویس دهنده ادامه دهید، حتی اگر مرورگرهای جدیدتر ممکن است آنها را نادیده بگیرند.
توسعهدهندگان میتوانند از این فرصت برای تصمیمگیری استفاده کنند که آیا میخواهند صراحتاً اسکریپتهای وارد شده خود را از حافظه پنهان HTTP کنار بگذارند یا خیر، و در صورت لزوم، updateViaCache: 'none'
به ثبتنام کارگر سرویس خود.
ارائه اسکریپت های وارداتی
با شروع Chrome 78، توسعهدهندگان ممکن است درخواستهای HTTP ورودی بیشتری را برای منابع بارگیری شده از طریق importScripts()
ببینند، زیرا اکنون برای بهروزرسانی بررسی میشوند.
اگر میخواهید از این ترافیک HTTP اضافی اجتناب کنید، هنگام ارائه اسکریپتهایی که شامل semver یا هش میشوند، سرصفحههای Cache-Control
طولانیمدت را تنظیم کنید و به رفتار بهروزرسانی پیشفرض updateViaCache
مربوط به 'imports'
تکیه کنید.
از طرف دیگر، اگر میخواهید اسکریپتهای وارد شده شما برای بهروزرسانیهای مکرر بررسی شوند، مطمئن شوید که آنها را با Cache-Control: max-age=0
سرو میکنید یا از updateViaCache: 'none'
استفاده میکنید.
در ادامه مطلب
« چرخه عمر کارگر خدمات » و « بهترین شیوههای ذخیره و حداکثر سن »، هر دو توسط جیک آرچیبالد، خواندن برای همه توسعهدهندگانی که هر چیزی را در وب اجرا میکنند توصیه میشود.