ذخیره منابع در زمان اجرا

برخی از دارایی ها در برنامه وب شما ممکن است به ندرت استفاده شوند، بسیار بزرگ باشند، یا بر اساس دستگاه کاربر (مانند تصاویر پاسخگو) یا زبان متفاوت باشند. اینها مواردی هستند که در آن پیش کش ممکن است یک ضد الگو باشد و به جای آن باید به کش در زمان اجرا تکیه کنید.

در Workbox، می‌توانید با استفاده از ماژول workbox-routing برای مطابقت دادن مسیرها، کش کردن زمان اجرا برای دارایی‌ها را مدیریت کنید، و با ماژول workbox-strategies ، استراتژی‌های کش کردن آن‌ها را مدیریت کنید.

استراتژی های ذخیره سازی

با یکی از استراتژی‌های ذخیره‌سازی داخلی می‌توانید اکثر مسیرها را برای دارایی‌ها مدیریت کنید. آنها قبلاً در این مستندات به تفصیل پوشش داده شده‌اند ، اما در اینجا به چند مورد اشاره می‌کنیم:

  • Stale while Revalidate از یک پاسخ ذخیره شده برای درخواست در صورت موجود بودن استفاده می کند و حافظه پنهان را در پس زمینه با پاسخی از شبکه به روز می کند. بنابراین، اگر دارایی کش نباشد، منتظر پاسخ شبکه می ماند و از آن استفاده می کند. این یک استراتژی نسبتاً ایمن است، زیرا به طور منظم ورودی‌های کش را که به آن متکی هستند به روز می‌کند. نکته منفی این است که همیشه یک دارایی از شبکه در پس‌زمینه درخواست می‌کند.
  • Network First ابتدا سعی می کند پاسخی از شبکه دریافت کند. اگر پاسخی دریافت شود، آن پاسخ را به مرورگر ارسال می کند و آن را در حافظه پنهان ذخیره می کند. اگر درخواست شبکه ناموفق باشد، آخرین پاسخ ذخیره شده در حافظه پنهان استفاده می شود و دسترسی آفلاین به دارایی را امکان پذیر می کند.
  • Cache First ابتدا کش را برای پاسخ بررسی می کند و در صورت وجود از آن استفاده می کند. اگر درخواست در حافظه پنهان نباشد، از شبکه استفاده می شود و هر پاسخ معتبر قبل از ارسال به مرورگر به حافظه پنهان اضافه می شود.
  • Network Only پاسخ را مجبور می کند که از شبکه بیاید.
  • Cache فقط پاسخ را مجبور می کند که از حافظه پنهان بیاید.

می‌توانید این استراتژی‌ها را برای انتخاب درخواست‌ها با استفاده از روش‌های ارائه‌شده توسط workbox-routing اعمال کنید.

بکارگیری استراتژی های کش با تطبیق مسیر

workbox-routing یک متد registerRoute را برای تطبیق مسیرها و مدیریت آنها با یک استراتژی کش نمایش می دهد. registerRoute یک شی Route را می پذیرد که به نوبه خود دو آرگومان را می پذیرد:

  1. یک رشته، عبارت منظم ، یا یک تماس پاسخ منطبق برای تعیین معیارهای تطبیق مسیر.
  2. یک کنترل کننده برای مسیر - معمولاً یک استراتژی ارائه شده توسط workbox-strategies .

تماس‌های منطبق برای تطبیق مسیرها ترجیح داده می‌شوند، زیرا آنها یک شی زمینه را ارائه می‌دهند که شامل شی Request ، رشته URL درخواست، رویداد واکشی و یک بولی از اینکه آیا درخواست درخواستی با منشأ یکسان است یا خیر.

سپس کنترل کننده مسیر منطبق را مدیریت می کند. در مثال زیر، مسیر جدیدی ایجاد می‌شود که با درخواست‌های تصویری با منبع مشابه مطابقت دارد، ابتدا حافظه پنهان را اعمال می‌کند و به استراتژی شبکه بازمی‌گردد .

// sw.js
import { registerRoute, Route } from 'workbox-routing';
import { CacheFirst } from 'workbox-strategies';

// A new route that matches same-origin image requests and handles
// them with the cache-first, falling back to network strategy:
const imageRoute = new Route(({ request, sameOrigin }) => {
  return sameOrigin && request.destination === 'image'
}, new CacheFirst());

// Register the new route
registerRoute(imageRoute);

استفاده از کش های متعدد

Workbox به شما امکان می دهد تا با استفاده از گزینه cacheName موجود در استراتژی های همراه، پاسخ های کش شده را در نمونه های Cache جداگانه قرار دهید.

در مثال زیر، تصاویر از استراتژی stale-while-veridate استفاده می کنند، در حالی که دارایی های CSS و JavaScript از یک کش برای بازگشت به استراتژی شبکه استفاده می کنند. مسیر هر دارایی، با افزودن ویژگی cacheName ، پاسخ‌ها را در حافظه‌های پنهان جداگانه قرار می‌دهد.

// sw.js
import { registerRoute, Route } from 'workbox-routing';
import { CacheFirst, StaleWhileRevalidate } from 'workbox-strategies';

// Handle images:
const imageRoute = new Route(({ request }) => {
  return request.destination === 'image'
}, new StaleWhileRevalidate({
  cacheName: 'images'
}));

// Handle scripts:
const scriptsRoute = new Route(({ request }) => {
  return request.destination === 'script';
}, new CacheFirst({
  cacheName: 'scripts'
}));

// Handle styles:
const stylesRoute = new Route(({ request }) => {
  return request.destination === 'style';
}, new CacheFirst({
  cacheName: 'styles'
}));

// Register routes
registerRoute(imageRoute);
registerRoute(scriptsRoute);
registerRoute(stylesRoute);
تصویری از فهرستی از نمونه های کش در برگه برنامه DevTools کروم. سه کش متمایز نشان داده شده است: یکی با نام «اسکریپت ها»، دیگری با نام «سبک ها» و آخرین مورد با نام «تصاویر».
نمایش‌دهنده حافظه پنهان در پانل برنامه‌های Chrome DevTools. پاسخ‌ها برای انواع مختلف دارایی در حافظه پنهان جداگانه ذخیره می‌شوند.

تنظیم انقضا برای ورودی های حافظه پنهان

هنگام مدیریت کش(های) حافظه پنهان کارمند سرویس، از سهمیه های ذخیره سازی آگاه باشید. ExpirationPlugin نگهداری کش را ساده می کند و با workbox-expiration در معرض نمایش قرار می گیرد. برای استفاده از آن، آن را در پیکربندی یک استراتژی کش مشخص کنید:

// sw.js
import { registerRoute, Route } from 'workbox-routing';
import { CacheFirst } from 'workbox-strategies';
import { ExpirationPlugin } from 'workbox-expiration';

// Evict image cache entries older thirty days:
const imageRoute = new Route(({ request }) => {
  return request.destination === 'image';
}, new CacheFirst({
  cacheName: 'images',
  plugins: [
    new ExpirationPlugin({
      maxAgeSeconds: 60 * 60 * 24 * 30,
    })
  ]
}));

// Evict the least-used script cache entries when
// the cache has more than 50 entries:
const scriptsRoute = new Route(({ request }) => {
  return request.destination === 'script';
}, new CacheFirst({
  cacheName: 'scripts',
  plugins: [
    new ExpirationPlugin({
      maxEntries: 50,
    })
  ]
}));

// Register routes
registerRoute(imageRoute);
registerRoute(scriptsRoute);

رعایت سهمیه های ذخیره سازی می تواند پیچیده باشد. این تمرین خوبی است که کاربرانی را در نظر بگیرید که ممکن است فشار ذخیره سازی را تجربه کنند یا می خواهند از ذخیره سازی خود به بهترین شکل استفاده کنند. جفت ExpirationPlugin Workbox می تواند در دستیابی به آن هدف کمک کند.

ملاحظات مبدأ متقابل

تعامل بین کارمند خدمات شما و دارایی های متقاطع به طور قابل توجهی با دارایی های با منشاء مشابه متفاوت است. به اشتراک گذاری منابع متقاطع (CORS) پیچیده است، و این پیچیدگی به نحوه مدیریت منابع متقاطع در یک سرویس دهنده گسترش می یابد.

پاسخ های غیر شفاف

هنگام ایجاد یک درخواست متقاطع در حالت no-cors ، پاسخ را می توان در حافظه پنهان سرویس کار ذخیره کرد و حتی به طور مستقیم توسط مرورگر استفاده کرد. با این حال، خود بدنه پاسخ را نمی توان از طریق جاوا اسکریپت خواند. این به عنوان یک پاسخ غیر شفاف شناخته می شود.

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

به یاد داشته باشید که در حالت CORS شرکت کنید

حتی اگر دارایی‌های متقاطع را بارگیری کنید که سرصفحه‌های مجاز CORS را تنظیم می‌کنند که به شما امکان خواندن پاسخ‌ها را می‌دهد، ممکن است بدنه پاسخ منبع متقاطع همچنان مبهم باشد. برای مثال، HTML زیر درخواست‌های no-cors را راه‌اندازی می‌کند که بدون توجه به اینکه چه سرصفحه‌های CORS تنظیم شده‌اند، منجر به پاسخ‌های مبهم می‌شود:

<link rel="stylesheet" href="https://example.com/path/to/style.css">
<img src="https://example.com/path/to/image.png">

برای راه‌اندازی صریح درخواست cors که پاسخی غیر شفاف ایجاد می‌کند، باید صریحاً با افزودن ویژگی crossorigin به HTML خود، در حالت CORS شرکت کنید:

<link crossorigin="anonymous" rel="stylesheet" href="https://example.com/path/to/style.css">
<img crossorigin="anonymous" src="https://example.com/path/to/image.png">

این مهم است که به یاد داشته باشید زمانی که مسیرها در سرویس کارگر شما در زمان اجرا بارگیری می شوند.

Workbox ممکن است پاسخ‌های غیر شفاف را در حافظه پنهان ذخیره نکند

به‌طور پیش‌فرض، Workbox رویکرد محتاطانه‌ای برای ذخیره‌سازی پاسخ‌های غیرشفاف دارد. از آنجایی که بررسی کد پاسخ برای پاسخ‌های غیرشفاف غیرممکن است، ذخیره کردن پاسخ خطا در حافظه پنهان می‌تواند منجر به تجربه‌ای دائماً شکسته شود، اگر از یک استراتژی cache-first یا cache-only استفاده شود.

اگر نیاز دارید که یک پاسخ غیر شفاف را در Workbox ذخیره کنید، باید از یک استراتژی شبکه اول یا stale-while-validate برای مدیریت آن استفاده کنید. بله، این بدان معنی است که دارایی همچنان از شبکه درخواست می شود، اما تضمین می کند که پاسخ های ناموفق ادامه نخواهند داشت و در نهایت با پاسخ های قابل استفاده جایگزین می شوند.

اگر از استراتژی ذخیره‌سازی دیگری استفاده می‌کنید و یک پاسخ غیرشفاف برگردانده می‌شود، Workbox به شما هشدار می‌دهد که در حالت توسعه ، پاسخ در حافظه پنهان ذخیره نشده است.

ذخیره اجباری پاسخ های غیر شفاف

اگر کاملاً مطمئن هستید که می‌خواهید یک پاسخ غیر شفاف را با استفاده از استراتژی cache-first یا cache only ذخیره کنید، می‌توانید Workbox را با ماژول workbox-cacheable-response مجبور کنید این کار را انجام دهد:

import {Route, registerRoute} from 'workbox-routing';
import {NetworkFirst, StaleWhileRevalidate} from 'workbox-strategies';
import {CacheableResponsePlugin} from 'workbox-cacheable-response';

const cdnRoute = new Route(({url}) => {
  return url === 'https://cdn.google.com/example-script.min.js';
}, new CacheFirst({
  plugins: [
    new CacheableResponsePlugin({
      statuses: [0, 200]
    })
  ]
}))

registerRoute(cdnRoute);

پاسخ های غیر شفاف و navigator.storage API

برای جلوگیری از نشت اطلاعات بین دامنه‌ای، به اندازه یک پاسخ غیرشفاف که برای محاسبه محدودیت‌های سهمیه ذخیره‌سازی استفاده می‌شود، بالشتک قابل توجهی اضافه شده است. این بر نحوه گزارش API navigator.storage بر سهمیه‌های ذخیره‌سازی تأثیر می‌گذارد.

این بالشتک بسته به مرورگر متفاوت است، اما برای Chrome، حداقل اندازه ای که هر پاسخ غیر شفاف ذخیره شده در حافظه پنهان به کل فضای ذخیره سازی استفاده شده کمک می کند تقریباً 7 مگابایت است. هنگام تعیین تعداد پاسخ‌های غیر شفافی که می‌خواهید حافظه پنهان کنید، باید این را در نظر داشته باشید، زیرا به راحتی می‌توانید از سهمیه‌های ذخیره‌سازی خیلی زودتر از آنچه که در غیر این صورت انتظار دارید، فراتر بروید.