برخی از وب سایت ها ممکن است نیاز به برقراری ارتباط با کارمند خدمات بدون نیاز به اطلاع از نتیجه داشته باشند. در اینجا چند نمونه آورده شده است:
- یک صفحه فهرستی از URLها را برای واکشی اولیه به سرویسکار می فرستد، به طوری که وقتی کاربر روی پیوندی کلیک می کند، سند یا منابع فرعی صفحه از قبل در حافظه پنهان موجود است و پیمایش بعدی را بسیار سریعتر می کند.
- این صفحه از کارمند خدمات می خواهد که مجموعه ای از مقالات برتر را بازیابی و ذخیره کند تا آنها را برای اهداف آفلاین در دسترس قرار دهد.
واگذاری این نوع وظایف غیر حیاتی به کارمند خدمات این مزیت را دارد که رشته اصلی را برای مدیریت بهتر وظایف مهمتر مانند پاسخگویی به تعاملات کاربر آزاد می کند.
در این راهنما نحوه پیادهسازی تکنیک ارتباط یکطرفه از صفحه به سرویسکار را با استفاده از APIهای استاندارد مرورگر و کتابخانه Workbox بررسی خواهیم کرد. ما این نوع موارد استفاده را ذخیره سازی ضروری می نامیم.
مورد تولید
1-800-Flowers.com برای تسریع در پیمایش بعدی به صفحات جزئیات محصول ، کش کردن ضروری (پیش واکشی) را با کارکنان سرویس از طریق postMessage()
برای واکشی اولیه موارد برتر در صفحات دسته بندی اجرا کرد.
آنها از یک رویکرد ترکیبی برای تصمیم گیری اینکه کدام موارد را از قبل واکشی کنند استفاده می کنند:
- در زمان بارگذاری صفحه، از کارگر سرویسدهنده میخواهند که دادههای JSON را برای 9 مورد برتر بازیابی کند و اشیاء پاسخ حاصل را به حافظه پنهان اضافه کند.
- برای موارد باقیمانده، آنها به رویداد
mouseover
گوش می دهند، به طوری که، وقتی کاربر مکان نما را روی یک آیتم حرکت می دهد، می تواند یک واکشی برای منبع "در صورت تقاضا" راه اندازی کند.
آنها از Cache API برای ذخیره پاسخ های JSON استفاده می کنند:
هنگامی که کاربر روی یک مورد کلیک میکند، دادههای JSON مرتبط با آن را میتوان بدون نیاز به رفتن به شبکه از حافظه پنهان برداشت و ناوبری را سریعتر کرد.
با استفاده از Workbox
Workbox یک راه آسان برای ارسال پیام به یک سرویس دهنده، از طریق بسته workbox-window
، مجموعهای از ماژولهایی که برای اجرا در زمینه پنجره در نظر گرفته شده است، فراهم میکند. آنها مکمل سایر بسته های Workbox هستند که در سرویس کار اجرا می شوند.
برای برقراری ارتباط صفحه با سرویسکار، ابتدا یک مرجع شی Workbox به سرویسکار ثبتشده دریافت کنید:
const wb = new Workbox('/sw.js');
wb.register();
سپس میتوانید مستقیماً پیام را به صورت اعلامی ارسال کنید، بدون اینکه مشکلی برای ثبت نام، بررسی فعالسازی، یا فکر کردن در مورد API ارتباطی اساسی داشته باشید:
wb.messageSW({"type": "PREFETCH", "payload": {"urls": ["/data1.json", "data2.json"]}}); });
سرویس دهنده یک کنترل کننده message
را برای گوش دادن به این پیام ها پیاده سازی می کند. میتواند به صورت اختیاری پاسخی را برگرداند، اگرچه در مواردی مانند این، لازم نیست:
self.addEventListener('message', (event) => {
if (event.data && event.data.type === 'PREFETCH') {
// do something
}
});
استفاده از API های مرورگر
اگر کتابخانه Workbox برای نیازهای شما کافی نیست، در اینجا نحوه اجرای ارتباط پنجره به سرویس کارگر با استفاده از APIهای مرورگر آمده است.
API postMessage می تواند برای ایجاد یک مکانیسم ارتباطی یک طرفه از صفحه به کارگر سرویس استفاده شود.
صفحه postMessage()
در رابط سرویس کارگر فراخوانی می کند:
navigator.serviceWorker.controller.postMessage({
type: 'MSG_ID',
payload: 'some data to perform the task',
});
سرویس دهنده یک کنترل کننده message
را برای گوش دادن به این پیام ها پیاده سازی می کند.
self.addEventListener('message', (event) => {
if (event.data && event.data.type === MSG_ID) {
// do something
}
});
مشخصه {type : 'MSG_ID'}
مطلقاً مورد نیاز نیست، اما این یکی از راههایی است که به صفحه اجازه میدهد انواع مختلف دستورالعملها را برای سرویسکار ارسال کند (یعنی «واکشی اولیه» در مقابل «پاک کردن فضای ذخیرهسازی»). سرویس دهنده می تواند بر اساس این پرچم به مسیرهای اجرایی مختلف منشعب شود.
اگر عملیات موفقیت آمیز بود، کاربر می تواند از مزایای آن بهره مند شود، اما در غیر این صورت، جریان کاربر اصلی را تغییر نمی دهد. به عنوان مثال، هنگامی که 1-800-Flowers.com سعی می کند پیش کش کند، صفحه نیازی به دانستن اینکه آیا سرویس دهنده موفق بوده است یا خیر. اگر اینطور باشد، کاربر از ناوبری سریعتر لذت خواهد برد. اگر این کار را نکرد، صفحه همچنان باید به صفحه جدید بروید. فقط کمی بیشتر طول می کشد.
یک مثال ساده از پیش واکشی
یکی از رایجترین کاربردهای کش اجباری، واکشی اولیه است، به معنای واکشی منابع برای یک URL معین، قبل از اینکه کاربر به سمت آن حرکت کند، تا سرعت ناوبری را افزایش دهد.
روشهای مختلفی برای اجرای پیش واکشی در سایتها وجود دارد:
- استفاده از تگ های پیش واکشی پیوند در صفحات: منابع به مدت پنج دقیقه در حافظه پنهان مرورگر نگهداری می شوند و پس از آن قوانین عادی
Cache-Control
برای منبع اعمال می شود. - تکمیل تکنیک قبلی با یک استراتژی کش در زمان اجرا در سرویسکار برای افزایش طول عمر منبع prefetch فراتر از این حد.
برای سناریوهای واکشی اولیه نسبتاً ساده، مانند واکشی اولیه اسناد، یا داراییهای خاص (JS، CSS و غیره)، این تکنیکها بهترین رویکرد هستند.
اگر منطق اضافی مورد نیاز است، به عنوان مثال، تجزیه منبع واکشی اولیه (یک فایل یا صفحه JSON) به منظور واکشی URL های داخلی آن، بهتر است این کار را به طور کامل به کارمند سرویس واگذار کنید.
واگذاری این نوع عملیات به کارگر خدماتی دارای مزایای زیر است:
- بارگیری سنگین کردن واکشی و پردازش پس از واکشی (که بعداً معرفی خواهد شد) به یک نخ ثانویه. با انجام این کار، رشته اصلی را برای انجام وظایف مهمتر مانند پاسخ به تعاملات کاربر آزاد می کند.
- اجازه دادن به چندین کلاینت (مثلاً برگه ها) برای استفاده مجدد از یک عملکرد مشترک، و حتی فراخوانی سرویس به طور همزمان بدون مسدود کردن رشته اصلی.
صفحات جزئیات محصول را از قبل واکشی کنید
ابتدا از postMessage()
در رابط کاربر سرویس استفاده کنید و آرایه ای از URL ها را به کش ارسال کنید:
navigator.serviceWorker.controller.postMessage({
type: 'PREFETCH',
payload: {
urls: [
'www.exmaple.com/apis/data_1.json',
'www.exmaple.com/apis/data_2.json',
],
},
});
در Service Worker، یک کنترل کننده message
را برای رهگیری و پردازش پیام های ارسال شده توسط هر برگه فعال پیاده سازی کنید:
addEventListener('message', (event) => {
let data = event.data;
if (data && data.type === 'PREFETCH') {
let urls = data.payload.urls;
for (let i in urls) {
fetchAsync(urls[i]);
}
}
});
در کد قبلی یک تابع کمکی کوچک به نام fetchAsync()
معرفی کردیم تا روی آرایه URL ها تکرار شود و برای هر یک از آنها درخواست واکشی صادر کند:
async function fetchAsync(url) {
// await response of fetch call
let prefetched = await fetch(url);
// (optionally) cache resources in the service worker storage
}
هنگامی که پاسخ به دست آمد، می توانید به سربرگ های ذخیره منبع تکیه کنید. اگرچه در بسیاری از موارد، مانند صفحات جزئیات محصول، منابع ذخیره نمیشوند (به این معنی که آنها یک هدر Cache-control
no-cache
دارند). در مواردی مانند این، میتوانید با ذخیره منبع واکشی شده در کش سرویس کار، این رفتار را لغو کنید. این مزیت اضافی را دارد که به فایل اجازه می دهد در سناریوهای آفلاین ارائه شود.
فراتر از داده های JSON
هنگامی که دادههای JSON از نقطه پایانی سرور واکشی میشوند، اغلب حاوی نشانیهای اینترنتی دیگری هستند که ارزش واکشی اولیه را نیز دارند، مانند یک تصویر یا سایر دادههای نقطه پایانی که با این دادههای سطح اول مرتبط هستند.
بیایید بگوییم که در مثال ما، داده های JSON بازگردانده شده اطلاعات یک سایت خرید مواد غذایی است:
{
"productName": "banana",
"productPic": "https://cdn.example.com/product_images/banana.jpeg",
"unitPrice": "1.99"
}
کد fetchAsync()
تغییر دهید تا روی لیست محصولات تکرار شود و تصویر قهرمان برای هر یک از آنها ذخیره شود:
async function fetchAsync(url, postProcess) {
// await response of fetch call
let prefetched = await fetch(url);
//(optionally) cache resource in the service worker cache
// carry out the post fetch process if supplied
if (postProcess) {
await postProcess(prefetched);
}
}
async function postProcess(prefetched) {
let productJson = await prefetched.json();
if (productJson && productJson.product_pic) {
fetchAsync(productJson.product_pic);
}
}
میتوانید برای موقعیتهایی مانند 404 در اطراف این کد، کنترل استثنایی اضافه کنید. اما زیبایی استفاده از سرویسکار برای واکشی اولیه این است که میتواند بدون عواقب زیادی برای صفحه و موضوع اصلی شکست بخورد. همچنین ممکن است منطق مفصل تری در پس پردازش محتوای از پیش واکشی شده داشته باشید که آن را انعطاف پذیرتر کرده و با داده هایی که مدیریت می کند جدا می شود. آسمان حد است
نتیجه گیری
در این مقاله، یک مورد استفاده رایج از ارتباط یک طرفه بین صفحه و کارگر سرویس را پوشش دادیم: حافظه پنهان ضروری . مثالهای مورد بحث فقط برای نشان دادن یک روش استفاده از این الگو هستند و همین رویکرد را میتوان برای موارد استفاده دیگر نیز به کار برد، بهعنوان مثال، ذخیره مقالات برتر در صورت تقاضا برای مصرف آفلاین، نشانکگذاری و موارد دیگر.
برای الگوهای بیشتر ارتباط با صفحه و کارکنان خدمات، بررسی کنید:
- بهروزرسانیهای پخش : تماس با صفحه از طرف سرویسدهنده برای اطلاع از بهروزرسانیهای مهم (مثلاً نسخه جدیدی از برنامه وب موجود است).
- ارتباط دو طرفه : تفویض یک کار به یک کارگر خدماتی (مثلاً یک بارگیری سنگین)، و اطلاع رسانی صفحه از پیشرفت.