{"id":325203,"date":"2021-06-20T15:00:26","date_gmt":"2021-06-20T15:00:26","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=325203"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=325203","title":{"rendered":"\u0418\u0434\u0435\u0430\u043b\u044c\u043d\u044b\u0439 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442 \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u043f\u0440\u043e\u0433\u0440\u0435\u0441\u0441\u0438\u0432\u043d\u044b\u0445 \u0432\u0435\u0431-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439 \u0438\u043b\u0438 \u0412\u0441\u0435, \u0447\u0442\u043e \u0432\u044b \u0445\u043e\u0442\u0435\u043b\u0438 \u0437\u043d\u0430\u0442\u044c \u043e Workbox. \u0427\u0430\u0441\u0442\u044c 1"},"content":{"rendered":"\n<div class=\"post__text post__text-html post__text_v1\" id=\"post-content-body\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/q3\/h3\/mw\/q3h3mwmy5zsl-8i3svvhojkmyww.png\">  <\/p>\n<h2 id=\"chto-takoe-workbox\">\u0427\u0442\u043e \u0442\u0430\u043a\u043e\u0435 <code>Workbox<\/code>?<\/h2>\n<p>  <\/p>\n<p><a href=\"https:\/\/developers.google.com\/web\/tools\/workbox\"><code>Workbox<\/code><\/a> (\u0434\u0430\u043b\u0435\u0435 \u2014 <code>WB<\/code>) \u2014 \u044d\u0442\u043e \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 (\u0442\u043e\u0447\u043d\u0435\u0435, \u043d\u0430\u0431\u043e\u0440 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a), \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0439 \u0446\u0435\u043b\u044c\u044e \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f &quot;\u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043b\u0443\u0447\u0448\u0438\u0445 \u043f\u0440\u0430\u043a\u0442\u0438\u043a \u0438 \u0438\u0437\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043e\u0442 \u0448\u0430\u0431\u043b\u043e\u043d\u043d\u043e\u0433\u043e \u043a\u043e\u0434\u0430 \u043f\u0440\u0438 \u0440\u0430\u0431\u043e\u0442\u0435 \u0441 \u0441\u0435\u0440\u0432\u0438\u0441-\u0432\u043e\u0440\u043a\u0435\u0440\u0430\u043c\u0438&quot; (\u0434\u0430\u043b\u0435\u0435 \u2014 \u0421\u0412).<\/p>\n<p>  <\/p>\n<p>\u0415\u0441\u043b\u0438 \u0432\u044b \u0432\u043f\u0435\u0440\u0432\u044b\u0435 \u0441\u043b\u044b\u0448\u0438\u0442\u0435 \u043e \u0421\u0412, \u0442\u043e \u043f\u0435\u0440\u0435\u0434 \u0438\u0437\u0443\u0447\u0435\u043d\u0438\u0435\u043c \u0434\u0430\u043d\u043d\u043e\u0433\u043e \u0440\u0443\u043a\u043e\u0432\u043e\u0434\u0441\u0442\u0432\u0430 \u043d\u0430\u0441\u0442\u043e\u044f\u0442\u0435\u043b\u044c\u043d\u043e \u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0443\u0435\u0442\u0441\u044f \u043e\u0437\u043d\u0430\u043a\u043e\u043c\u0438\u0442\u044c\u0441\u044f \u0441\u043e \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c\u0438 \u043c\u0430\u0442\u0435\u0440\u0438\u0430\u043b\u0430\u043c\u0438:<\/p>\n<p>  <\/p>\n<ul>\n<li><a href=\"https:\/\/developer.mozilla.org\/ru\/docs\/Web\/API\/Service_Worker_API\">Service Worker API \u2014 MDN<\/a><\/li>\n<li><a href=\"https:\/\/developers.google.com\/web\/fundamentals\/primers\/service-workers\">Service Workers: an Introduction \u2014 Web Fundamentals<\/a><\/li>\n<li><a href=\"https:\/\/habr.com\/ru\/post\/491840\/\">\u0412\u0438\u0437\u0443\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441\u0435\u0440\u0432\u0438\u0441-\u0432\u043e\u0440\u043a\u0435\u0440\u043e\u0432 \u2014 \u0425\u0430\u0431\u0440<\/a><\/li>\n<li><a href=\"https:\/\/habr.com\/ru\/post\/517672\/\">\u0420\u0435\u0446\u0435\u043f\u0442\u044b \u043f\u043e \u043f\u0440\u0438\u0433\u043e\u0442\u043e\u0432\u043b\u0435\u043d\u0438\u044e \u043e\u0444\u043b\u0430\u0439\u043d-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439 \u2014 \u0425\u0430\u0431\u0440<\/a><\/li>\n<\/ul>\n<p>  <\/p>\n<p><code>WB<\/code> \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438:<\/p>\n<p>  <\/p>\n<ul>\n<li>\u043f\u0440\u0435\u0434\u0432\u0430\u0440\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0435 \u043a\u044d\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435<\/li>\n<li>\u043a\u044d\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f<\/li>\n<li>\u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u0438 (\u043a\u044d\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f)<\/li>\n<li>\u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 (\u043f\u0435\u0440\u0435\u0445\u0432\u0430\u0442 \u0441\u0435\u0442\u0435\u0432\u044b\u0445) \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432<\/li>\n<li>\u0444\u043e\u043d\u043e\u0432\u0430\u044f \u0441\u0438\u043d\u0445\u0440\u043e\u043d\u0438\u0437\u0430\u0446\u0438\u044f<\/li>\n<li>\u043f\u043e\u043c\u043e\u0449\u044c \u0432 \u043e\u0442\u043b\u0430\u0434\u043a\u0435<\/li>\n<\/ul>\n<p>  <\/p>\n<h2 id=\"na-chto-pohozh-wb-api\">\u041d\u0430 \u0447\u0442\u043e \u043f\u043e\u0445\u043e\u0436 <code>WB API<\/code>?<\/h2>\n<p>  <\/p>\n<p>\u041d\u0438\u0436\u0435 \u043f\u0440\u0438\u0432\u0435\u0434\u0435\u043d\u044b \u043f\u0440\u0438\u043c\u0435\u0440\u044b \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0445 \u043f\u043e\u0434\u0445\u043e\u0434\u043e\u0432 \u043a \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0435 \u043f\u0440\u043e\u0433\u0440\u0435\u0441\u0441\u0438\u0432\u043d\u044b\u0445 \u0432\u0435\u0431-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439 (\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439, \u0432 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442\u0441\u044f \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438, \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u043c\u044b\u0435 \u0421\u0412).<\/p>\n<p><a name=\"habracut\"><\/a>  <\/p>\n<h3 id=\"keshirovanie-shriftov-google\">\u041a\u044d\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0448\u0440\u0438\u0444\u0442\u043e\u0432 Google<\/h3>\n<p>  <\/p>\n<p>\u0425\u043e\u0442\u0435\u043b\u0438 \u0431\u044b \u0432\u044b, \u0447\u0442\u043e\u0431\u044b \u0432\u0430\u0448\u0438 \u0433\u0443\u0433\u043b-\u0448\u0440\u0438\u0444\u0442\u044b \u0431\u044b\u043b\u0438 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b \u0432 \u0440\u0435\u0436\u0438\u043c\u0435 \u043e\u0444\u043b\u0430\u0439\u043d \u043f\u043e\u0441\u043b\u0435 \u0442\u043e\u0433\u043e, \u043a\u0430\u043a \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0432 \u043f\u0435\u0440\u0432\u044b\u0439 \u0440\u0430\u0437 \u043f\u043e\u0441\u0435\u0442\u0438\u043b \u0432\u0430\u0448 \u0441\u0430\u0439\u0442? \u0422\u043e\u0433\u0434\u0430 \u0437\u0430\u043f\u0438\u0448\u0438\u0442\u0435 \u0438\u0445 \u0432 \u043a\u044d\u0448:<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">import { ExpirationPlugin } from 'workbox-expiration' import { registerRoute } from 'workbox-routing' import { StaleWhileRevalidate } from 'workbox-strategies'  \/\/ \u0417\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u043c \u0433\u0443\u0433\u043b-\u0448\u0440\u0438\u0444\u0442\u044b \u0432 \u043a\u044d\u0448 \u0441 \u043f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u0438\u0435\u043c \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u0438 `stale-while-revalidate` (\u0441\u043c. \u043d\u0438\u0436\u0435) \u0441 \/\/ \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u0435\u043c \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u0430 \u0432\u0445\u043e\u0436\u0434\u0435\u043d\u0438\u0439 (\u0437\u0430\u043f\u0438\u0441\u0435\u0439 \u0432 \u043a\u044d\u0448\u0435) registerRoute(   ({ url }) =&gt;  url.origin === 'https:\/\/fonts.googleapis.com' ||                 url.origin === 'https:\/\/fonts.gstatic.com',   new StaleWhileRevalidate({     cacheName: 'google-fonts',     plugins: [       new ExpirationPlugin({ maxEntries: 20 })     ]   }) )<\/code><\/pre>\n<p>  <\/p>\n<h3 id=\"keshirovanie-javascript-i-css\">\u041a\u044d\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 <code>JavaScript<\/code> \u0438 <code>CSS<\/code><\/h3>\n<p>  <\/p>\n<p>\u0421\u0434\u0435\u043b\u0430\u0439\u0442\u0435 \u0432\u0430\u0448 <code>JS<\/code> \u0438 <code>CSS-\u043a\u043e\u0434<\/code> \u0431\u044b\u0441\u0442\u0440\u044b\u043c \u0437\u0430 \u0441\u0447\u0435\u0442 \u0435\u0433\u043e \u0434\u043e\u0441\u0442\u0430\u0432\u043a\u0438 \u0438\u0437 \u043a\u044d\u0448\u0430, \u0431\u0443\u0434\u0443\u0447\u0438 \u0443\u0432\u0435\u0440\u0435\u043d\u043d\u044b\u043c\u0438 \u0432 \u0435\u0433\u043e \u0430\u043a\u0442\u0443\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u0437\u0430 \u0441\u0447\u0435\u0442 \u043f\u0435\u0440\u0438\u043e\u0434\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f (\u0432 \u0444\u043e\u043d\u043e\u0432\u043e\u043c \u0440\u0435\u0436\u0438\u043c\u0435):<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">import { registerRoute } from 'workbox-routing' import { StaleWhileRevalidate } from 'workbox-strategies'  registerRoute(   ({ request }) =&gt;  request.destination === 'script' ||                     request.destination === 'style',   new StaleWhileRevalidate() )<\/code><\/pre>\n<p>  <\/p>\n<h3 id=\"keshirovanie-izobrazheniy\">\u041a\u044d\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0439<\/h3>\n<p>  <\/p>\n<p>\u041a\u0430\u043a \u043f\u0440\u0430\u0432\u0438\u043b\u043e, \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0439 &quot;\u0432\u0435\u0441&quot; \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b \u2014 \u044d\u0442\u043e \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f. \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0439\u0442\u0435 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0435 \u043f\u0440\u0430\u0432\u0438\u043b\u043e \u0434\u043b\u044f \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0439 \u0432 \u043a\u044d\u0448\u0435, \u0431\u0443\u0434\u0443\u0447\u0438 \u0443\u0432\u0435\u0440\u0435\u043d\u043d\u044b\u043c\u0438, \u0447\u0442\u043e \u043e\u043d\u0438 \u043d\u0435 \u043f\u0435\u0440\u0435\u043f\u043e\u043b\u043d\u044f\u0442 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f:<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">import { CacheableResponsePlugin } from 'workbox-cacheable-response' import { CacheFirst } from 'workbox-strategies' import { ExpirationPlugin } from 'workbox-expiration' import { registerRoute } from 'workbox-routing'  registerRoute(   ({ register }) =&gt; request.destination === 'image',   new CacheFirst({     cacheName: 'images',     plugins: [       new CacheableResponsePlugin({         statuses: [0, 200]       }),       new ExpirationPlugin({         maxEntries: 60,         maxAgeSeconds: 30 * 24 * 60 * 60 \/\/ 30 \u0434\u043d\u0435\u0439       })     ]   }) )<\/code><\/pre>\n<p>  <\/p>\n<h3 id=\"predvaritelnoe-keshirovanie\">\u041f\u0440\u0435\u0434\u0432\u0430\u0440\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0435 \u043a\u044d\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435<\/h3>\n<p>  <\/p>\n<p>\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0439\u0442\u0435 <code>WB<\/code> \u0434\u043b\u044f \u043f\u0440\u0435\u0434\u0432\u0430\u0440\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0433\u043e \u043a\u044d\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u044b\u0445 \u0432\u0430\u0448\u0438\u043c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435\u043c, \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e <code>CLI<\/code>, <code>Node-\u043c\u043e\u0434\u0443\u043b\u044f<\/code> \u0438\u043b\u0438 <code>Webpack-\u043f\u043b\u0430\u0433\u0438\u043d\u0430<\/code>.<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">\/\/ CLI workbox wizard  \/\/ Node const { generateSW } = require('workbox-build')  generateSW({   swDest: '.\/build\/sw.js',   globDirectory: '.\/app',   globPatterns: '**\/*.{js, css, html, png}' })  \/\/ Webpack const { GenerateSW } = require('workbox-webpack-plugin')  module.exports = {   \/\/ \u0434\u0440\u0443\u0433\u0438\u0435 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u0432\u0435\u0431\u043f\u0430\u043a\u0430   plugins: [     \/\/ \u0434\u0440\u0443\u0433\u0438\u0435 \u043f\u043b\u0430\u0433\u0438\u043d\u044b     new GenerateSW()   ] }<\/code><\/pre>\n<p>  <\/p>\n<h3 id=\"gugl-analitika-v-rezhime-oflayn\">\u0413\u0443\u0433\u043b-\u0430\u043d\u0430\u043b\u0438\u0442\u0438\u043a\u0430 \u0432 \u0440\u0435\u0436\u0438\u043c\u0435 \u043e\u0444\u043b\u0430\u0439\u043d<\/h3>\n<p>  <\/p>\n<p>\u0425\u043e\u0442\u0438\u0442\u0435, \u0447\u0442\u043e\u0431\u044b \u0433\u0443\u0433\u043b-\u0430\u043d\u0430\u043b\u0438\u0442\u0438\u043a\u0430 \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0430\u043b\u0430 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u043f\u0440\u0438 \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0438\u0438 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u043a \u0441\u0435\u0442\u0438? \u041d\u0438\u043a\u0430\u043a\u0438\u0445 \u043f\u0440\u043e\u0431\u043b\u0435\u043c.<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">import * as googleAnalytics from 'wortkbox-google-analytics'  googleAnalytics.initialize()<\/code><\/pre>\n<p>  <\/p>\n<h2 id=\"nachalo-raboty\">\u041d\u0430\u0447\u0430\u043b\u043e \u0440\u0430\u0431\u043e\u0442\u044b<\/h2>\n<p>  <\/p>\n<p><code>WB<\/code> \u2014 \u044d\u0442\u043e \u043d\u0430\u0431\u043e\u0440 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a \u0434\u043b\u044f \u043f\u043e\u043c\u043e\u0449\u0438 \u0432 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0438 \u0438 \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0438 \u0421\u0412 \u0438 \u043a\u044d\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u0447\u0435\u0440\u0435\u0437 <a href=\"https:\/\/developer.mozilla.org\/ru\/docs\/Web\/API\/CacheStorage\"><code>CacheStorage API<\/code><\/a>. \u0421\u0412 \u0438 <code>CacheStorage API<\/code> \u043f\u0440\u0438 \u0441\u043e\u0432\u043c\u0435\u0441\u0442\u043d\u043e\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0438 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0442 \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c \u0442\u0435\u043c, \u043e\u0442\u043a\u0443\u0434\u0430 \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u044e\u0442\u0441\u044f \u0440\u0435\u0441\u0443\u0440\u0441\u044b, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u044b\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435\u043c (<code>JavaScript<\/code>, <code>CSS<\/code>, <code>HTML<\/code>, \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0438 \u0442.\u0434.), \u0438\u0437 \u0441\u0435\u0442\u0438 \u0438\u043b\u0438 \u0438\u0437 \u043a\u044d\u0448\u0430.<\/p>\n<p>  <\/p>\n<h3 id=\"ustanovka\">\u0423\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430<\/h3>\n<p>  <\/p>\n<p>\u041d\u0430\u0447\u0438\u043d\u0430\u044f \u0441 5 \u0432\u0435\u0440\u0441\u0438\u0438, <code>WB<\/code> \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d \u0432\u043d\u0443\u0442\u0440\u0438 \u0421\u0412 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e <code>JS-\u043c\u043e\u0434\u0443\u043b\u0435\u0439<\/code> \u0438 <code>npm<\/code> \u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u043e\u043c \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0445 \u043c\u043e\u0434\u0443\u043b\u0435\u0439 <code>WB<\/code> \u0438 \u0438\u0445 \u0438\u043c\u043f\u043e\u0440\u0442\u0430.<\/p>\n<p>  <\/p>\n<p>\u041a \u0441\u043e\u0436\u0430\u043b\u0435\u043d\u0438\u044e, <code>JS-\u043c\u043e\u0434\u0443\u043b\u0438<\/code> \u043d\u0435 \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0442 \u0432 \u0421\u0412, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0434\u043b\u044f \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u0438 \u0421\u0412 \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0441\u0431\u043e\u0440\u0449\u0438\u043a \u043c\u043e\u0434\u0443\u043b\u0435\u0439, \u0442\u0430\u043a\u043e\u0439 \u043a\u0430\u043a <code>Webpack<\/code>, <code>Rollup<\/code> \u0438\u043b\u0438 <code>Parcel<\/code> (\u0441\u043c. \u043d\u0438\u0436\u0435).<\/p>\n<p>  <\/p>\n<h3 id=\"sozdanie-sv\">\u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0421\u0412<\/h3>\n<p>  <\/p>\n<p>\u041f\u0435\u0440\u0435\u0434 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c <code>WB<\/code>, \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0421\u0412 \u0438 \u0437\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0435\u0433\u043e \u043d\u0430 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0435. \u041d\u0430\u0447\u043d\u0435\u043c \u0441 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0444\u0430\u0439\u043b\u0430 <code>service-worker.js<\/code> \u0432 \u043a\u043e\u0440\u043d\u0435\u0432\u043e\u0439 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u0438 \u043f\u0440\u043e\u0435\u043a\u0442\u0430:<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">console.log('\u041f\u0440\u0438\u0432\u0435\u0442 \u043e\u0442 \u0441\u0435\u0440\u0432\u0438\u0441-\u0432\u043e\u0440\u043a\u0435\u0440\u0430!')<\/code><\/pre>\n<p>  <\/p>\n<p>\u0414\u0430\u043b\u0435\u0435 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u0443\u0435\u043c \u0421\u0412 \u043d\u0430 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0435:<\/p>\n<p>  <\/p>\n<pre><code class=\"html\">&lt;script&gt; \/\/ \u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0443 \u0421\u0412 if ('serviceWorker' in navigator) {   \/\/ \u041e\u0436\u0438\u0434\u0430\u0435\u043c \u043f\u043e\u043b\u043d\u043e\u0439 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b   window.addEventListener('load', () =&gt; {     navigator.serviceWorker.register('\/service-worker.js')   }) } &lt;\/script&gt;<\/code><\/pre>\n<p>  <\/p>\n<p>\u042d\u0442\u043e \u0441\u043e\u043e\u0431\u0449\u0430\u0435\u0442 \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0443, \u0447\u0442\u043e \u0434\u0430\u043d\u043d\u044b\u0439 \u0421\u0412 \u0434\u043e\u043b\u0436\u0435\u043d \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0434\u043b\u044f \u0442\u0435\u043a\u0443\u0449\u0435\u0439 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b. \u0415\u0441\u043b\u0438 \u0432\u044b \u043f\u0435\u0440\u0435\u0437\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u0435 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443, \u043e\u0442\u043a\u0440\u043e\u0435\u0442\u0435 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u044b \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0430 <code>Chrome<\/code> \u0438 \u043f\u0435\u0440\u0435\u0439\u0434\u0435\u0442\u0435 \u0432\u043e \u0432\u043a\u043b\u0430\u0434\u043a\u0443 <code>Console<\/code>, \u0442\u043e \u0443\u0432\u0438\u0434\u0438\u0442\u0435 \u0442\u0430\u043c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u043e\u0442 \u0421\u0412.<\/p>\n<p>  <\/p>\n<p>\u0415\u0441\u043b\u0438 \u043f\u0435\u0440\u0435\u043a\u043b\u044e\u0447\u0438\u0442\u044c\u0441\u044f \u043d\u0430 \u0432\u043a\u043b\u0430\u0434\u043a\u0443 <code>Application<\/code>, \u0442\u043e \u043c\u043e\u0436\u043d\u043e \u0443\u0432\u0438\u0434\u0435\u0442\u044c, \u0447\u0442\u043e \u0421\u0412 \u0431\u044b\u043b \u0443\u0441\u043f\u0435\u0448\u043d\u043e \u0437\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u043d.<\/p>\n<p>  <\/p>\n<p>\u041f\u043e\u0441\u043b\u0435 \u044d\u0442\u043e\u0433\u043e \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0430\u0442\u044c <code>WB<\/code>.<\/p>\n<p>  <\/p>\n<h2 id=\"ispolzovanie-wb\">\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 <code>WB<\/code><\/h2>\n<p>  <\/p>\n<p><code>WB<\/code> \u2014 \u044d\u0442\u043e \u043d\u0430\u0431\u043e\u0440 <code>npm-\u043c\u043e\u0434\u0443\u043b\u0435\u0439<\/code>. \u0421\u043d\u0430\u0447\u0430\u043b\u0430 \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u043d\u0443\u0436\u043d\u044b\u0439 \u043c\u043e\u0434\u0443\u043b\u044c, \u0437\u0430\u0442\u0435\u043c \u0438\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0435\u0433\u043e. \u041e\u0434\u043d\u0438\u043c\u0438 \u0438\u0437 \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0445 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0435\u0439 <code>WB<\/code> \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0438\u0437\u0430\u0446\u0438\u044f \u0438 \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u0438 \u043a\u044d\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f, \u0441 \u043d\u0438\u0445 \u0438 \u043d\u0430\u0447\u043d\u0435\u043c.<\/p>\n<p>  <\/p>\n<h3 id=\"marshrutizaciya-i-strategii-keshirovaniya\">\u041c\u0430\u0440\u0448\u0440\u0443\u0442\u0438\u0437\u0430\u0446\u0438\u044f \u0438 \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u0438 \u043a\u044d\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f<\/h3>\n<p>  <\/p>\n<p><code>WB<\/code> \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c \u043a\u044d\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435\u043c HTTP-\u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0445 \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u0439 \u043a\u044d\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f. \u041f\u0435\u0440\u0432\u044b\u043c \u0434\u0435\u043b\u043e\u043c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u0442\u044c, \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u0435\u0442 \u043b\u0438 \u043f\u043e\u0441\u0442\u0443\u043f\u0438\u0432\u0448\u0438\u0439 \u0437\u0430\u043f\u0440\u043e\u0441 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u043e\u043c\u0443 \u043a\u0440\u0438\u0442\u0435\u0440\u0438\u044e \u0438, \u0435\u0441\u043b\u0438 \u044d\u0442\u043e \u0442\u0430\u043a, \u043f\u0440\u0438\u043c\u0435\u043d\u0438\u0442\u044c \u043a \u043d\u0435\u043c\u0443 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0443\u044e \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u044e. \u041c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043f\u0440\u0435\u0434\u0432\u0430\u0440\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u0443\u044e \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u044e (\u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u043c\u0443\u044e <code>WB<\/code>) \u0438\u043b\u0438 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u0442\u044c \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u0443\u044e. \u0411\u0430\u0437\u043e\u0432\u0430\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0438\u0437\u0430\u0446\u0438\u0438 \u0438 \u043a\u044d\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u043c\u043e\u0436\u0435\u0442 \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c \u0442\u0430\u043a:<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">import { registerRoute } from 'workbox-routing' import {   NetworkFirst,   StaleWhileRevalidate,   CacheFirst } from 'workbox-strategies'  \/\/ \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0434\u043b\u044f \u0444\u0438\u043b\u044c\u0442\u0440\u0430\u0446\u0438\u0438 \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u0441\u0442\u0430\u0442\u0443\u0441-\u043a\u043e\u0434\u043e\u0432, \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043a\u043e\u0432 \u0438\u043b\u0438 \u043e\u0431\u043e\u0438\u0445 \u0441\u0440\u0430\u0437\u0443 (\u0441\u043c. \u043d\u0438\u0436\u0435) import { CacheableResponsePlugin } from 'workbox-cacheable-response' \/\/ \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0434\u043b\u044f \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u044f \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u0430 \u0437\u0430\u043f\u0438\u0441\u0435\u0439 \u0432 \u043a\u044d\u0448\u0435 \u0438 \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u044f \u0437\u0430\u043f\u0438\u0441\u0435\u0439 \u043f\u043e \u0438\u0441\u0442\u0435\u0447\u0435\u043d\u0438\u0438 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u043e\u0433\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u0438 (\u0441\u043c. \u043d\u0438\u0436\u0435) import { ExpirationPlugin } from 'workbox-expiration'  \/\/ \u041a\u044d\u0448\u0438\u0440\u0443\u0435\u043c \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b (`HTML`) \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u0438 `Network First` (\u0441\u043d\u0430\u0447\u0430\u043b\u0430 \u0441\u0435\u0442\u044c) registerRoute(   \/\/ \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c, \u0447\u0442\u043e \u0437\u0430\u043f\u0440\u043e\u0441 - \u044d\u0442\u043e \u043f\u0435\u0440\u0435\u0445\u043e\u0434 \u043d\u0430 \u043d\u043e\u0432\u0443\u044e \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443   ({ request }) =&gt; request.mode === 'navigate',   new NetworkFirst({     \/\/ \u043f\u043e\u043c\u0435\u0449\u0430\u0435\u043c \u0432\u0441\u0435 \u0444\u0430\u0439\u043b\u044b \u0432 \u043a\u044d\u0448 \u0441 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435\u043c 'pages'     cacheName: 'pages',     plugins: [       \/\/ \u043a\u044d\u0448\u0438\u0440\u0443\u0435\u043c \u0442\u043e\u043b\u044c\u043a\u043e \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b \u0441\u043e \u0441\u0442\u0430\u0442\u0443\u0441\u043e\u043c 200       new CacheableResponsePlugin({         statuses: [200]       })     ]   }) )  \/\/ \u041a\u044d\u0448\u0438\u0440\u0443\u0435\u043c \u0437\u0430\u043f\u0440\u043e\u0441\u044b \u043d\u0430 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 `CSS`, `JS` \u0438 \u0432\u0435\u0431-\u0432\u043e\u0440\u043a\u0435\u0440\u043e\u0432 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u0438 `Stale While Revalidate` (\u0441\u0447\u0438\u0442\u0430\u0435\u0442\u0441\u044f \u0443\u0441\u0442\u0430\u0440\u0435\u0432\u0448\u0438\u043c \u043f\u043e\u0441\u043b\u0435 \u0437\u0430\u043f\u0440\u043e\u0441\u0430) registerRoute({   \/\/ \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c, \u0447\u0442\u043e \u0446\u0435\u043b\u044c \u0437\u0430\u043f\u0440\u043e\u0441\u0430 - \u044d\u0442\u043e \u0442\u0430\u0431\u043b\u0438\u0446\u0430 \u0441\u0442\u0438\u043b\u0435\u0439, \u0441\u043a\u0440\u0438\u043f\u0442 \u0438\u043b\u0438 \u0432\u043e\u0440\u043a\u0435\u0440   ({ request }) =&gt;     request.destination === 'style' ||     request.destination === 'script' ||     request.destination === 'worker',   new StaleWhileRevalidate({     \/\/ \u043f\u043e\u043c\u0435\u0449\u0430\u0435\u043c \u0444\u0430\u0439\u043b\u044b \u0432 \u043a\u044d\u0448 \u0441 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435\u043c 'assets'     cacheName: 'assets',     plugins: [       new CacheableResponsePlugin({         statuses: [200]       })     ]   }) })  \/\/ \u041a\u044d\u0448\u0438\u0440\u0443\u0435\u043c \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u0438 `Cache First` (\u0441\u043d\u0430\u0447\u0430\u043b\u0430 \u043a\u044d\u0448) registerRoute(   \/\/ \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c, \u0447\u0442\u043e \u0446\u0435\u043b\u044c \u0437\u0430\u043f\u0440\u043e\u0441\u0430 - \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435   ({ request }) =&gt; request.destination === 'image',   new CacheFirst({     \/\/ \u043f\u043e\u043c\u0435\u0449\u0430\u0435\u043c \u0444\u0430\u0439\u043b\u044b \u0432 \u043a\u044d\u0448 \u0441 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435\u043c 'images'     cacheName: 'images',     plugins: [       new CacheableResponsePlugin({         statuses: [200]       }),       \/\/ \u043a\u044d\u0448\u0438\u0440\u0443\u0435\u043c \u0434\u043e 50 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0439 \u0432 \u0442\u0435\u0447\u0435\u043d\u0438\u0435 30 \u0434\u043d\u0435\u0439       new ExpirationPlugin({         maxEntries: 50,         maxAgeSeconds: 60 * 60 * 24 * 30       })     ]   }) )<\/code><\/pre>\n<p>  <\/p>\n<h3 id=\"predvaritelnoe-keshirovanie-1\">\u041f\u0440\u0435\u0434\u0432\u0430\u0440\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0435 \u043a\u044d\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435<\/h3>\n<p>  <\/p>\n<p>\u0412 \u0434\u043e\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u043a \u043a\u044d\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044e \u043f\u043e\u0441\u043b\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0437\u0430\u043f\u0440\u043e\u0441\u0430 (\u043a\u044d\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044e \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f), <code>WB<\/code> \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 \u043f\u0440\u0435\u0434\u0432\u0430\u0440\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0435 \u043a\u044d\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u2014 \u043a\u044d\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432 \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438 \u0421\u0412. \u0425\u043e\u0440\u043e\u0448\u0438\u043c\u0438 \u043a\u0430\u043d\u0434\u0438\u0434\u0430\u0442\u0430\u043c\u0438 \u0434\u043b\u044f \u043f\u0440\u0435\u0434\u0432\u0430\u0440\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0433\u043e \u043a\u044d\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u043d\u0430\u0447\u0430\u043b\u044c\u043d\u044b\u0439 <code>URL<\/code> \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f, \u0440\u0435\u0437\u0435\u0440\u0432\u043d\u0430\u044f (\u043e\u0444\u043b\u0430\u0439\u043d) \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430, \u0430 \u0442\u0430\u043a\u0436\u0435 \u043a\u043b\u044e\u0447\u0435\u0432\u044b\u0435 <code>JS<\/code> \u0438 <code>CSS-\u0444\u0430\u0439\u043b\u044b<\/code>. \u041f\u0440\u0435\u0434\u0432\u0430\u0440\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0435 \u043a\u044d\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0433\u0430\u0440\u0430\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c, \u0447\u0442\u043e \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0435 \u0440\u0435\u0441\u0443\u0440\u0441\u044b \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u043c\u0438 \u0432 \u043c\u043e\u043c\u0435\u043d\u0442, \u043a\u043e\u0433\u0434\u0430 \u0421\u0412 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u044c \u043d\u0430\u0434 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0435\u0439.<\/p>\n<p>  <\/p>\n<p>\u041f\u0440\u0435\u0434\u0432\u0430\u0440\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0435 \u043a\u044d\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0432\u043d\u0443\u0442\u0440\u0438 \u0421\u0412 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043f\u043b\u0430\u0433\u0438\u043d\u0430, \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u043c\u043e\u0433\u043e \u0441\u0431\u043e\u0440\u0449\u0438\u043a\u043e\u043c \u043c\u043e\u0434\u0443\u043b\u0435\u0439, \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u044e\u0449\u0438\u043c \u0432\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u043d\u0438\u0435 (\u0432\u043d\u0435\u0434\u0440\u0435\u043d\u0438\u0435) \u201c\u043c\u0430\u043d\u0438\u0444\u0435\u0441\u0442\u0430 \u043f\u0440\u0435\u0434\u0432\u0430\u0440\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0433\u043e \u043a\u044d\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f\u201d (\u0441\u043c. \u043d\u0438\u0436\u0435):<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">import { precacheAndRoute } from 'workbox-precaching'  precacheAndRoute(self.__WB_MANIFEST)<\/code><\/pre>\n<p>  <\/p>\n<p>\u0414\u0430\u043d\u043d\u044b\u0439 \u0421\u0412 \u043f\u0440\u0435\u0434\u0432\u0430\u0440\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043a\u044d\u0448\u0438\u0440\u0443\u0435\u0442 \u0444\u0430\u0439\u043b\u044b \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438, \u0437\u0430\u043c\u0435\u043d\u044f\u044f <code>self.__WB_MANIFEST<\/code> \u0441\u043f\u0438\u0441\u043a\u043e\u043c \u0432\u0445\u043e\u0436\u0434\u0435\u043d\u0438\u0439, \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c\u044b\u0445 \u0432 \u0421\u0412 \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u0441\u0431\u043e\u0440\u043a\u0438.<\/p>\n<p>  <\/p>\n<h3 id=\"rezervnyy-kontent\">\u0420\u0435\u0437\u0435\u0440\u0432\u043d\u044b\u0439 \u043a\u043e\u043d\u0442\u0435\u043d\u0442<\/h3>\n<p>  <\/p>\n<p>\u041a\u0430\u043a \u043f\u0440\u0430\u0432\u0438\u043b\u043e, \u0434\u043b\u044f \u043f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u043a\u0438 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u043a \u0440\u0430\u0431\u043e\u0442\u0435 \u0432 \u0440\u0435\u0436\u0438\u043c\u0435 \u043e\u0444\u043b\u0430\u0439\u043d \u0432\u043c\u0435\u0441\u0442\u043e &quot;\u0434\u0435\u0444\u043e\u043b\u0442\u043d\u043e\u0439&quot; \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b \u0441 \u043e\u0448\u0438\u0431\u043a\u043e\u0439 \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0440\u0435\u0437\u0435\u0440\u0432\u043d\u0430\u044f \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430. \u0421 \u043f\u043e\u043c\u043e\u0449\u044c\u044e <code>WB<\/code> \u044d\u0442\u043e\u0442 \u043f\u0430\u0442\u0442\u0435\u0440\u043d \u043c\u043e\u0436\u043d\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u043f\u0440\u0438 \u043f\u043e\u043c\u043e\u0449\u0438 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 \u0441\u0442\u0440\u043e\u043a \u043a\u043e\u0434\u0430:<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">import { precacheAndRoute } from 'workbox-precaching' import { setCatchHandler } from 'workbox-routing'  \/\/ \u041e\u0431\u0435\u0441\u043f\u0435\u0447\u0438\u0432\u0430\u0435\u043c \u043a\u044d\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 `\/offline.html` \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u0441\u0431\u043e\u0440\u043a\u0438 precacheAndRoute(self.__WB_MANIFEST)  \/\/ \u041f\u0435\u0440\u0435\u0445\u0432\u0430\u0442\u044b\u0432\u0430\u0435\u043c \u043e\u0448\u0438\u0431\u043a\u0438, \u0441\u0432\u044f\u0437\u0430\u043d\u043d\u044b\u0435 \u0441 \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0438\u0437\u0430\u0446\u0438\u0435\u0439, \u0442\u0430\u043a\u0438\u0435 \u043a\u0430\u043a \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0438\u0435 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u043a \u0441\u0435\u0442\u0438 setCatchHandler(async ({ event }) =&gt; {   \/\/ \u0412\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c \u043f\u0440\u0435\u0434\u0432\u0430\u0440\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u043d\u0443\u044e \u0440\u0435\u0437\u0435\u0440\u0432\u043d\u0443\u044e \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443 \u043f\u0440\u0438 \u0437\u0430\u043f\u0440\u043e\u0441\u0435 \u201c\u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u201d   if (event.request.destination === 'document') {     return matchPrecache('\/offline.html')   }    return Response.error() })<\/code><\/pre>\n<p>  <\/p>\n<p>\u0414\u0430\u043d\u043d\u044b\u0439 \u0421\u0412 \u043f\u0440\u0435\u0434\u0432\u0430\u0440\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u0442 \u0440\u0435\u0437\u0435\u0440\u0432\u043d\u0443\u044e \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443 \u0438 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0435\u0435 \u043f\u0440\u0438 \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0438\u0438 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u043a \u0441\u0435\u0442\u0438 \u0432\u043c\u0435\u0441\u0442\u043e \u043e\u0448\u0438\u0431\u043a\u0438.<\/p>\n<p>  <\/p>\n<h2 id=\"ispolzovanie-sborschikov-moduley-s-wb\">\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u0441\u0431\u043e\u0440\u0449\u0438\u043a\u043e\u0432 \u043c\u043e\u0434\u0443\u043b\u0435\u0439 \u0441 <code>WB<\/code><\/h2>\n<p>  <\/p>\n<p>\u041a\u0430\u043a \u0431\u044b\u043b\u043e \u043e\u0442\u043c\u0435\u0447\u0435\u043d\u043e \u0440\u0430\u043d\u0435\u0435, \u043d\u0430\u0447\u0438\u043d\u0430\u044f \u0441 5 \u0432\u0435\u0440\u0441\u0438\u0438, <code>WB<\/code> \u043c\u043e\u0436\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0432 \u0421\u0412 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e <code>JS-\u043c\u043e\u0434\u0443\u043b\u0435\u0439<\/code>.<\/p>\n<p>  <\/p>\n<h3 id=\"sozdanie-sborki\">\u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0441\u0431\u043e\u0440\u043a\u0438<\/h3>\n<p>  <\/p>\n<p><strong>\u0412\u044b\u0431\u043e\u0440 \u0441\u0431\u043e\u0440\u0449\u0438\u043a\u0430 \u043c\u043e\u0434\u0443\u043b\u0435\u0439<\/strong><\/p>\n<p>  <\/p>\n<p>\u041f\u043e\u0434\u043e\u0439\u0434\u0435\u0442 \u043b\u044e\u0431\u043e\u0439 \u0441\u0431\u043e\u0440\u0449\u0438\u043a, \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u044e\u0449\u0438\u0439 \u043c\u043e\u0434\u0443\u043b\u0438, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, <a href=\"https:\/\/webpack.js.org\/\"><code>Webpack<\/code><\/a>, <a href=\"https:\/\/rollupjs.org\/guide\/en\/\"><code>Rollup<\/code><\/a> \u0438\u043b\u0438 <a href=\"https:\/\/parceljs.org\/\"><code>Parcel<\/code><\/a>.<\/p>\n<p>  <\/p>\n<p><strong>\u041d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u043a\u043e\u0434\u0430 \u0421\u0412<\/strong><\/p>\n<p>  <\/p>\n<p>\u041d\u0438\u0436\u0435 \u043f\u0440\u0438\u0432\u0435\u0434\u0435\u043d \u043f\u0440\u0438\u043c\u0435\u0440 \u0433\u0438\u043f\u043e\u0442\u0435\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u0421\u0412, \u0438\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u0443\u044e\u0449\u0435\u0433\u043e \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e <code>WB-\u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a<\/code>. \u0414\u0430\u043d\u043d\u044b\u0439 \u0421\u0412 \u0434\u043e\u043b\u0436\u0435\u043d \u0431\u044b\u0442\u044c \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0430\u043d \u0441\u0431\u043e\u0440\u0449\u0438\u043a\u043e\u043c \u043f\u0435\u0440\u0435\u0434 \u0437\u0430\u043f\u0443\u0441\u043a\u043e\u043c \u0432 \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0435.<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">import { precacheAndRoute } from 'workbox-precaching' import { registerRoute } from 'workbox-routing' import { CacheFirst } from 'workbox-strategies'  \/\/ \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0438\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 \u0434\u043b\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043a\u044d\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f, \/\/ \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0438\u0437\u0430\u0446\u0438\u0438 \u0438 \u0434\u0440\u0443\u0433\u043e\u0439 \u043b\u043e\u0433\u0438\u043a\u0438 precacheAndRoute(self.__WB_MANIFEST)  registerRoute(   ({ request }) =&gt; request.destination === 'image',   new CacheFirst({ cacheName: 'images' }) )  \/\/ \u0438 \u0442.\u0434.<\/code><\/pre>\n<p>  <\/p>\n<p>\u0421\u043b\u0435\u0434\u0443\u0435\u0442 \u043e\u0442\u043c\u0435\u0442\u0438\u0442\u044c, \u0447\u0442\u043e <code>WB<\/code> \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u043d\u043e\u0435 \u043b\u043e\u0433\u0433\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0432 \u0440\u0435\u0436\u0438\u043c\u0435 \u0434\u043b\u044f \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0438 \u043c\u0438\u043d\u0438\u043c\u0430\u043b\u044c\u043d\u043e\u0435 \u043b\u043e\u0433\u0433\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0432 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u043c \u0440\u0435\u0436\u0438\u043c\u0435.<\/p>\n<p>  <\/p>\n<p><strong>\u041e\u043f\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e: \u0432\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u043d\u0438\u0435 \u043c\u0430\u043d\u0438\u0444\u0435\u0441\u0442\u0430 \u043f\u0440\u0435\u0434\u0432\u0430\u0440\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0433\u043e \u043a\u044d\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f<\/strong><\/p>\n<p>  <\/p>\n<p>\u0414\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u043a\u044d\u0448\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0440\u0435\u0441\u0443\u0440\u0441\u044b \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438 \u0421\u0412, \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u0438\u0442\u044c <code>WB<\/code> \u043e\u0444\u043e\u0440\u043c\u043b\u0435\u043d\u043d\u044b\u0439 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u044b\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c \u0441\u043f\u0438\u0441\u043e\u043a <code>URL<\/code>. \u0414\u0430\u043d\u043d\u044b\u0439 \u0441\u043f\u0438\u0441\u043e\u043a \u043d\u0430\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u201c\u043c\u0430\u043d\u0438\u0444\u0435\u0441\u0442\u043e\u043c \u043f\u0440\u0435\u0434\u0432\u0430\u0440\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0433\u043e \u043a\u044d\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f\u201d (precaching manifest).<\/p>\n<p>  <\/p>\n<p>\u041c\u0435\u0441\u0442\u043e \u0434\u043b\u044f \u0432\u0441\u0442\u0430\u0432\u043a\u0438 \u0442\u0430\u043a\u043e\u0433\u043e \u043c\u0430\u043d\u0438\u0444\u0435\u0441\u0442\u0430 \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u0441\u0431\u043e\u0440\u043a\u0438 \u043e\u0431\u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442\u0441\u044f \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e <code>self.__WB_MANIFEST<\/code>.<\/p>\n<p>  <\/p>\n<p><strong>\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 \u0432\u0435\u0431\u043f\u0430\u043a\u0430<\/strong><\/p>\n<p>  <\/p>\n<p>\u041f\u043b\u0430\u0433\u0438\u043d <a href=\"https:\/\/developers.google.com\/web\/tools\/workbox\/modules\/workbox-webpack-plugin#injectmanifest_plugin\"><code>Inject Manifest<\/code><\/a> \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u043a\u0430\u043a \u0437\u0430 \u0441\u0431\u043e\u0440\u043a\u0443 \u0421\u0412, \u0442\u0430\u043a \u0438 \u0437\u0430 \u0432\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u043d\u0438\u0435 \u043c\u0430\u043d\u0438\u0444\u0435\u0441\u0442\u0430. \u041f\u0440\u0438 \u0435\u0433\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u043d\u0435 \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e \u043d\u0430\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0442\u044c \u0421\u0412.<\/p>\n<p>  <\/p>\n<p><strong>\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 CLI<\/strong><\/p>\n<p>  <\/p>\n<p>\u0412\u043c\u0435\u0441\u0442\u043e \u043f\u043b\u0430\u0433\u0438\u043d\u0430 \u0434\u043b\u044f \u0441\u0431\u043e\u0440\u0449\u0438\u043a\u0430 \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c <a href=\"https:\/\/developers.google.com\/web\/tools\/workbox\/modules\/workbox-cli\"><code>workbox-cli<\/code><\/a> \u0432 \u0440\u0435\u0436\u0438\u043c\u0435 <a href=\"https:\/\/developers.google.com\/web\/tools\/workbox\/modules\/workbox-cli#injectmanifest\"><code>injectManifest<\/code><\/a>.<\/p>\n<p>  <\/p>\n<p>\u041f\u0440\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0438 \u0434\u0430\u043d\u043d\u043e\u0433\u043e \u043f\u043e\u0434\u0445\u043e\u0434\u0430 \u043f\u043e\u0441\u043b\u0435 \u043a\u0430\u0436\u0434\u043e\u0439 \u0443\u0441\u043f\u0435\u0448\u043d\u043e\u0439 \u0441\u0431\u043e\u0440\u043a\u0438 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c <code>injectManifest<\/code>, \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u044f \u0435\u043c\u0443 \u0441\u0432\u0435\u0436\u0435\u0433\u043e \u0421\u0412 \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 <code>swSrc<\/code>.<\/p>\n<p>  <\/p>\n<p><strong><code>GenerateSW<\/code><\/strong><\/p>\n<p>  <\/p>\n<p>\u0412 \u0440\u0435\u0436\u0438\u043c\u0435 <code>generateSW<\/code> \u043f\u0440\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0438 <code>workbox-build<\/code>, <code>workbox-cli<\/code> \u0438\u043b\u0438 <code>GenerateSW<\/code> \u0432 <code>workbox-webpack-plugin<\/code> \u043d\u0435 \u043d\u0443\u0436\u043d\u043e \u043d\u0430\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0442\u044c \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u0441\u0431\u043e\u0440\u043a\u0438 \u2014 \u0433\u043e\u0442\u043e\u0432\u044b\u0439 \u043a \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044e \u0421\u0412 \u0431\u0443\u0434\u0435\u0442 \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438.<\/p>\n<p>  <\/p>\n<h2 id=\"obrabotka-zaprosov\">\u041e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432<\/h2>\n<p>  <\/p>\n<p>\u041c\u0430\u0440\u0448\u0440\u0443\u0442\u0438\u0437\u0430\u0446\u0438\u044f \u0432 <code>WB<\/code> \u2014 \u044d\u0442\u043e \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u044f \u0441\u043e\u0432\u043f\u0430\u0434\u0435\u043d\u0438\u044f \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0430 \u0441 \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u043c \u0438 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u0441\u043e\u0432\u043f\u0430\u0432\u0448\u0435\u0433\u043e \u0437\u0430\u043f\u0440\u043e\u0441\u0430 (\u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0430 \u043e\u0442\u0432\u0435\u0442\u0430 \u043d\u0430 \u043d\u0435\u0433\u043e).<\/p>\n<p>  <\/p>\n<p>\u0421\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 \u0442\u0440\u0438 \u0441\u043f\u043e\u0441\u043e\u0431\u0430 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u044f \u0441\u043e\u0432\u043f\u0430\u0434\u0435\u043d\u0438\u0439 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e <code>workbox-routing<\/code>:<\/p>\n<p>  <\/p>\n<ol>\n<li>\u0421\u0442\u0440\u043e\u043a\u0430<\/li>\n<li>\u0420\u0435\u0433\u0443\u043b\u044f\u0440\u043d\u043e\u0435 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435<\/li>\n<li>\u0424\u0443\u043d\u043a\u0446\u0438\u044f \u043e\u0431\u0440\u0430\u0442\u043d\u043e\u0433\u043e \u0432\u044b\u0437\u043e\u0432\u0430<\/li>\n<\/ol>\n<p>  <\/p>\n<h3 id=\"poisk-sovpadeniy\">\u041f\u043e\u0438\u0441\u043a \u0441\u043e\u0432\u043f\u0430\u0434\u0435\u043d\u0438\u0439<\/h3>\n<p>  <\/p>\n<p><strong>\u0421 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0441\u0442\u0440\u043e\u043a<\/strong><\/p>\n<p>  <\/p>\n<p>\u0417\u0430\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0435\u043c\u044b\u0439 <code>URL<\/code> \u0441\u0440\u0430\u0432\u043d\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0441\u043e \u0441\u0442\u0440\u043e\u043a\u043e\u0439 \u0438, \u0435\u0441\u043b\u0438 \u043e\u043d\u0438 \u0440\u0430\u0432\u043d\u044b, \u0437\u0430\u043f\u0440\u043e\u0441 \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u0442\u0441\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0443 (<code>handler<\/code>). \u041c\u0430\u0440\u0448\u0440\u0443\u0442\u0438\u0437\u0430\u0442\u043e\u0440 \u0434\u043b\u044f <code>\/logo.png<\/code> \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d \u0442\u0430\u043a:<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">import { registerRoute } from 'workbox-routing'  registerRoute('\/logo.png', handler)<\/code><\/pre>\n<p>  <\/p>\n<p>\u041f\u0440\u043e\u0431\u043b\u0435\u043c\u0430 \u0442\u0430\u043a\u043e\u0433\u043e \u043f\u043e\u0434\u0445\u043e\u0434\u0430 \u0441\u043e\u0441\u0442\u043e\u0438\u0442 \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u0437\u0430\u043f\u0440\u043e\u0441\u044b \u0438\u0437 \u0434\u0440\u0443\u0433\u043e\u0433\u043e \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u0430 (origin) \u043d\u0435 \u0431\u0443\u0434\u0443\u0442 \u0441\u043e\u0432\u043f\u0430\u0434\u0430\u0442\u044c \u0441\u043e \u0441\u0442\u0440\u043e\u043a\u043e\u0439. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u043b\u0443\u0447\u0448\u0435 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0442\u044c \u0430\u0431\u0441\u043e\u043b\u044e\u0442\u043d\u044b\u0439 \u043f\u0443\u0442\u044c:<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">import { registerRoute } from 'workbox-routing'  registerRoute('https:\/\/some-other-origin.com\/logo.png', handler)<\/code><\/pre>\n<p>  <\/p>\n<p><strong>\u0421 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0440\u0435\u0433\u0443\u043b\u044f\u0440\u043d\u044b\u0445 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0439<\/strong><\/p>\n<p>  <\/p>\n<p>\u041b\u0443\u0447\u0448\u0438\u043c \u0441\u043f\u043e\u0441\u043e\u0431\u043e\u043c \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0433\u0440\u0443\u043f\u043f\u044b \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u0440\u0435\u0433\u0443\u043b\u044f\u0440\u043d\u043e\u0433\u043e \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f.<\/p>\n<p>  <\/p>\n<p>\u0414\u0430\u043d\u043d\u044b\u0439 \u043f\u043e\u0434\u0445\u043e\u0434 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0433\u043e\u0440\u0430\u0437\u0434\u043e \u0431\u043e\u043b\u0435\u0435 \u0433\u0438\u0431\u043a\u0438\u043c, \u0447\u0435\u043c \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0438\u0439. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0432\u043e\u0442 \u043a\u0430\u043a \u043c\u043e\u0436\u043d\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0438\u0437\u0430\u0446\u0438\u044e \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u0439 \u0444\u0430\u0439\u043b\u043e\u0432:<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">import { registerRoute } from 'workbox-routing'  registerRoute(new RegExp('\\\\.js$'), jsHandler)  registerRoute(new RegExp('\\\\.css$'), cssHandler)<\/code><\/pre>\n<p>  <\/p>\n<p>\u0420\u0435\u0433\u0443\u043b\u044f\u0440\u043d\u044b\u0435 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0442\u0430\u043a\u0436\u0435 \u043c\u043e\u0433\u0443\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0434\u043b\u044f \u043f\u043e\u0438\u0441\u043a\u0430 \u0441\u043e\u0432\u043f\u0430\u0434\u0435\u043d\u0438\u044f \u0441 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u044b\u043c \u0444\u043e\u0440\u043c\u0430\u0442\u043e\u043c <code>URL<\/code>, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440:<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">\/\/ \/blog\/&lt;\u0433\u043e\u0434&gt;\/&lt;\u043c\u0435\u0441\u044f\u0446&gt;\/&lt;\u043f\u043e\u0441\u0442 \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043e\u043a \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440&gt; import { registerRoute } from 'workbox-routing'  registerRoute(new RegExp('\/blog\/\\\\d{4}\/\\\\d{2}\/.+'), handler)<\/code><\/pre>\n<p>  <\/p>\n<p>\u0418 \u0441\u043d\u043e\u0432\u0430 \u043d\u0430\u0448 \u043c\u0430\u0440\u0448\u0440\u0443\u0442 \u043d\u0435 \u0431\u0443\u0434\u0435\u0442 \u0441\u043e\u0432\u043f\u0430\u0434\u0430\u0442\u044c \u0441 \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u043c \u0438\u0437 \u0434\u0440\u0443\u0433\u043e\u0433\u043e \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u0430. \u042d\u0442\u0443 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0443 \u043c\u043e\u0436\u043d\u043e \u0440\u0435\u0448\u0438\u0442\u044c \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e <code>wildcard<\/code> (<code>.+<\/code>):<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">import { registerRoute } from 'workbox-routing'  registerRoute(new RegExp('.+\/blog\/\\\\d{4}\/\\\\d{2}\/.+'), handler)<\/code><\/pre>\n<p>  <\/p>\n<p>\u0422\u0430\u043a\u043e\u0439 \u0436\u0435 \u0444\u043e\u043a\u0443\u0441 \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u043e\u0434\u0435\u043b\u0430\u0442\u044c \u0441 \u043f\u0435\u0440\u0432\u044b\u043c \u043f\u0440\u0438\u043c\u0435\u0440\u043e\u043c:<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">import { registerRoute } from 'workbox-routing'  registerRoute(new RegExp('.+\\\\.js$'), jsHandler)  registerRoute(new RegExp('.+\\\\.css$'), cssHandler)<\/code><\/pre>\n<p>  <\/p>\n<p><strong>\u0421 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043a\u043e\u043b\u0431\u044d\u043a\u043e\u0432<\/strong><\/p>\n<p>  <\/p>\n<p>\u0414\u043b\u044f \u0434\u0430\u043b\u044c\u043d\u0435\u0439\u0448\u0435\u0439 \u043a\u0430\u0441\u0442\u043e\u043c\u0438\u0437\u0430\u0446\u0438\u0438 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u044f \u0441\u043e\u0432\u043f\u0430\u0434\u0435\u043d\u0438\u0439 \u043c\u043e\u0436\u043d\u043e \u0432\u043e\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u0435\u0439 <a href=\"https:\/\/developers.google.com\/web\/tools\/workbox\/reference-docs\/latest\/module-workbox-routing#%7EmatchCallback\"><code>matchCallback<\/code><\/a>. \u0414\u0430\u043d\u043d\u0430\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/API\/ExtendableEvent\"><code>ExtendableEvent<\/code><\/a>, <a href=\"https:\/\/developer.mozilla.org\/ru\/docs\/Web\/API\/Request\"><code>Request<\/code><\/a> \u0438 \u043e\u0431\u044a\u0435\u043a\u0442 <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/API\/URL\"><code>URL<\/code><\/a>.<\/p>\n<p>  <\/p>\n<p>\u041f\u0440\u043e\u0441\u0442\u043e\u0439 \u043f\u0440\u0438\u043c\u0435\u0440:<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">import { registerRoute } from 'workbox-routing'  const matchFunction = ({ url, request, event }) =&gt; {   return url.href === 'https:\/\/example.com\/app.js' }  registerRoute(matchFunction, handler)<\/code><\/pre>\n<p>  <\/p>\n<h3 id=\"obrabotka-zaprosov-1\">\u041e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432<\/h3>\n<p>  <\/p>\n<p>\u0421\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 \u0434\u0432\u0430 \u0441\u043f\u043e\u0441\u043e\u0431\u0430 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432:<\/p>\n<p>  <\/p>\n<ol>\n<li>\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u043e\u0434\u043d\u043e\u0439 \u0438\u0437 \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u0439, \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u043c\u044b\u0445 <code>workbox-strategies<\/code><\/li>\n<li>\u041f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u043e\u0431\u0440\u0430\u0442\u043d\u043e\u0433\u043e \u0432\u044b\u0437\u043e\u0432\u0430, \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u044e\u0449\u0435\u0439 \u043f\u0440\u043e\u043c\u0438\u0441, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0440\u0430\u0437\u0440\u0435\u0448\u0430\u0435\u0442\u0441\u044f \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u043c <code>Response<\/code><\/li>\n<\/ol>\n<p>  <\/p>\n<p><strong>\u0421 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u0439<\/strong><\/p>\n<p>  <\/p>\n<p><code>WB<\/code> \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u0438 \u043a\u044d\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f:<\/p>\n<p>  <\/p>\n<ul>\n<li><code>Stale While Revalidate<\/code> (\u0440\u0435\u0441\u0443\u0440\u0441 \u0441\u0447\u0438\u0442\u0430\u0435\u0442\u0441\u044f \u0443\u0441\u0442\u0430\u0440\u0435\u0432\u0448\u0438\u043c \u043f\u043e\u0441\u043b\u0435 \u0437\u0430\u043f\u0440\u043e\u0441\u0430) \u2014 \u043e\u0442\u0432\u0435\u0442 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442\u0441\u044f \u0438\u0437 \u043a\u044d\u0448\u0430, \u043f\u043e\u0441\u043b\u0435 \u0447\u0435\u0433\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435 \u043a\u044d\u0448\u0430 \u0432 \u0444\u043e\u043d\u043e\u0432\u043e\u043c \u0440\u0435\u0436\u0438\u043c\u0435 (\u0435\u0441\u043b\u0438 \u043e\u0442\u0432\u0435\u0442 \u0435\u0449\u0435 \u043d\u0435 \u043a\u044d\u0448\u0438\u0440\u043e\u0432\u0430\u043d, \u043e\u043d \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442\u0441\u044f \u0438\u0437 \u0441\u0435\u0442\u0438). \u0414\u0430\u043d\u043d\u0430\u044f \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u044f \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e\u0439, \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u043a\u044d\u0448 \u0432\u0441\u0435 \u0432\u0440\u0435\u043c\u044f \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u0442\u0441\u044f. \u0415\u0435 \u043d\u0435\u0434\u043e\u0441\u0442\u0430\u0442\u043a\u043e\u043c \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043f\u043e\u0441\u0442\u043e\u044f\u043d\u043d\u044b\u0439 \u0437\u0430\u043f\u0440\u043e\u0441 \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432 \u0438\u0437 \u0441\u0435\u0442\u0438<\/li>\n<li><code>Network First<\/code> (\u0441\u043d\u0430\u0447\u0430\u043b\u0430 \u0441\u0435\u0442\u044c) \u2014 \u0441\u043f\u0435\u0440\u0432\u0430 \u043f\u0440\u0435\u0434\u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442\u0441\u044f \u043f\u043e\u043f\u044b\u0442\u043a\u0430 \u0432\u0435\u0440\u043d\u0443\u0442\u044c \u043e\u0442\u0432\u0435\u0442 \u0438\u0437 \u0441\u0435\u0442\u0438. \u0415\u0441\u043b\u0438 \u0434\u0430\u043d\u043d\u0430\u044f \u043f\u043e\u043f\u044b\u0442\u043a\u0430 \u0443\u0432\u0435\u043d\u0447\u0430\u043b\u0430\u0441\u044c \u0443\u0441\u043f\u0435\u0445\u043e\u043c, \u043e\u0442\u0432\u0435\u0442 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442\u0441\u044f \u0438 \u043f\u043e\u0441\u043b\u0435 \u044d\u0442\u043e\u0433\u043e \u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0432 \u043a\u044d\u0448. \u0412 \u043f\u0440\u043e\u0442\u0438\u0432\u043d\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435, \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442\u0441\u044f \u043e\u0442\u0432\u0435\u0442 \u0438\u0437 \u043a\u044d\u0448\u0430<\/li>\n<li><code>Cache First<\/code> (\u0441\u043d\u0430\u0447\u0430\u043b\u0430 \u043a\u044d\u0448) \u2014 \u0435\u0441\u043b\u0438 \u043e\u0442\u0432\u0435\u0442 \u0438\u043c\u0435\u0435\u0442\u0441\u044f \u0432 \u043a\u044d\u0448\u0435, \u043e\u043d \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442\u0441\u044f. \u0418\u043d\u0430\u0447\u0435 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0437\u0430\u043f\u0440\u043e\u0441 \u043a \u0441\u0435\u0442\u0438 \u0438 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u0439 (\u0432\u0430\u043b\u0438\u0434\u043d\u044b\u0439) \u043e\u0442\u0432\u0435\u0442 \u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0432 \u043a\u044d\u0448 \u0438 \u043f\u043e\u0441\u043b\u0435 \u044d\u0442\u043e\u0433\u043e \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u0442\u0441\u044f \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0443<\/li>\n<li><code>Network Only<\/code> (\u0442\u043e\u043b\u044c\u043a\u043e \u0441\u0435\u0442\u044c)<\/li>\n<li><code>Cache Only<\/code> (\u0442\u043e\u043b\u044c\u043a\u043e \u043a\u044d\u0448)<\/li>\n<\/ul>\n<p>  <\/p>\n<pre><code class=\"plaintext\">import { registerRoute } from 'workbox-routing' import * as strategies from 'workbox-strategies'  registerRoute(match, new strategies.StaleWhileRevalidate())  registerRoute(match, new strategies.NetworkFirst())  registerRoute(match, new strategies.CacheFirst())  registerRoute(match, new strategies.NetworkOnly())  registerRoute(match, new strategies.CacheOnly())<\/code><\/pre>\n<p>  <\/p>\n<p>\u041f\u043e\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0438\u0437\u0430\u0442\u043e\u0440\u0430 \u043f\u0440\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0438 \u043b\u044e\u0431\u043e\u0439 \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u0438 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043a\u0430\u0441\u0442\u043e\u043c\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043e \u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u043e\u043c \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u043e\u0433\u043e \u043a\u044d\u0448\u0430 \u0438\u043b\u0438 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u043f\u043b\u0430\u0433\u0438\u043d\u043e\u0432:<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">import { StaleWhileRevalidate } from 'workbox-strategies'  new StaleWhileRevalidate({    \/\/ \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u043a\u0430\u0441\u0442\u043e\u043c\u043d\u044b\u0439 \u043a\u044d\u0448   cacheName: 'my-cache-name',    \/\/ \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u043c\u0430\u0441\u0441\u0438\u0432 \u043f\u043b\u0430\u0433\u0438\u043d\u043e\u0432 (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, `ExpirationPlugin`)   plugins: [     ...   ] })<\/code><\/pre>\n<p>  <\/p>\n<p><strong>\u0421 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043a\u043e\u043b\u0431\u044d\u043a\u043e\u0432<\/strong><\/p>\n<p>  <\/p>\n<p>\u0414\u043b\u044f \u0434\u0430\u043b\u044c\u043d\u0435\u0439\u0448\u0435\u0439 \u043a\u0430\u0441\u0442\u043e\u043c\u0438\u0437\u0430\u0446\u0438\u0438 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 \u043c\u043e\u0436\u043d\u043e \u0432\u043e\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u044b\u043c \u043a\u043e\u043b\u0431\u044d\u043a\u043e\u043c, \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u044e\u0449\u0438\u043c \u043e\u0431\u044a\u0435\u043a\u0442 <code>Response<\/code>. \u0414\u0430\u043d\u043d\u044b\u0439 \u043a\u043e\u043b\u0431\u044d\u043a \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u043e\u0431\u044a\u0435\u043a\u0442 \u0441\u043e \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430\u043c\u0438 <code>url<\/code> \u0438 <code>event<\/code>:<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">import { registerRoute } from 'workbox-routing'  const handler = async ({ url, event }) =&gt; {   return new Response(`\u041e\u0442\u0432\u0435\u0442 \u043e\u0442 \u043a\u0430\u0441\u0442\u043e\u043c\u043d\u043e\u0433\u043e \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0430.`) }  registerRoute(match, handler)<\/code><\/pre>\n<p>  <\/p>\n<p>\u0421\u043b\u0435\u0434\u0443\u0435\u0442 \u043e\u0442\u043c\u0435\u0442\u0438\u0442\u044c, \u0447\u0442\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435, \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c\u043e\u0435 \u043a\u043e\u043b\u0431\u044d\u043a\u043e\u043c <code>match<\/code>, \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u0442\u0441\u044f \u0432 \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u043e\u0431\u0440\u0430\u0442\u043d\u043e\u0433\u043e \u0432\u044b\u0437\u043e\u0432\u0430 <code>handler<\/code> \u0432 \u0432\u0438\u0434\u0435 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u0430 <code>params<\/code>:<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">import { registerRoute } from 'workbox-routing'  const match = ({ url, event }) =&gt; {   if (url.pathname === '\/example') {     return {       name: 'Workbox',       type: '\u0420\u0443\u043a\u043e\u0432\u043e\u0434\u0441\u0442\u0432\u043e',     }   } }  const handler = async ({ url, event, params }) =&gt; {   \/\/ \u043e\u0442\u0432\u0435\u0442 \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c \u043a\u0430\u043a &quot;\u0420\u0443\u043a\u043e\u0432\u043e\u0434\u0441\u0442\u0432\u043e \u043f\u043e Workbox&quot;   return new Response(`${params.type} \u043f\u043e ${params.name}`) }  registerRoute(match, handler)<\/code><\/pre>\n<p>  <\/p>\n<p>\u042d\u0442\u043e \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043f\u043e\u043b\u0435\u0437\u043d\u044b\u043c, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0432 \u0441\u043b\u0443\u0447\u0430\u0435, \u043a\u043e\u0433\u0434\u0430 \u0443 \u043d\u0430\u0441 \u0438\u043c\u0435\u0435\u0442\u0441\u044f \u043a\u0430\u043a\u0430\u044f-\u0442\u043e \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438, \u201c\u0437\u0430\u0448\u0438\u0442\u0430\u044f\u201d \u0432 URL, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0438\u0437\u0432\u043b\u0435\u043a\u0430\u0435\u0442\u0441\u044f \u0432 <code>match<\/code> (\u043f\u0443\u0442\u0435\u043c \u0440\u0430\u0437\u0431\u043e\u0440\u0430 <code>URL<\/code>) \u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0432 <code>handler<\/code>.<\/p>\n<p>  <\/p>\n<h2 id=\"nastroyka-wb\">\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 <code>WB<\/code><\/h2>\n<p>  <\/p>\n<p><code>WB<\/code> \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u044f \u0434\u043b\u044f \u043a\u044d\u0448\u0430 \u0438 \u0443\u0440\u043e\u0432\u043d\u0438 \u043b\u043e\u0433\u0433\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0438\u0437 \u043a\u043e\u0440\u043e\u0431\u043a\u0438. \u042d\u0442\u0438 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u043c\u043e\u0436\u043d\u043e \u0438\u0437\u043c\u0435\u043d\u044f\u0442\u044c.<\/p>\n<p>  <\/p>\n<h3 id=\"nastroyka-nazvaniya-kesha\">\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u044f \u043a\u044d\u0448\u0430<\/h3>\n<p>  <\/p>\n<p>\u041f\u0440\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0438 \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0445 <code>WB API<\/code> \u043c\u043e\u0436\u043d\u043e \u0437\u0430\u043c\u0435\u0442\u0438\u0442\u044c, \u0447\u0442\u043e \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043a\u044d\u0448 \u0441\u043e\u0437\u0434\u0430\u0435\u0442\u0441\u044f \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438.<\/p>\n<p>  <\/p>\n<p>\u041f\u0440\u0438 \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0438\u0438 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0439 \u043a\u044d\u0448\u0430 <code>WB<\/code> \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 \u0434\u0435\u0444\u043e\u043b\u0442\u043d\u044b\u0435 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u044f, \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u044b\u0435 \u0432 <code>workbox-core<\/code>. \u041f\u0440\u0435\u0434\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u044b\u0435 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u044f \u043a\u044d\u0448\u0430 \u0432\u044b\u0433\u043b\u044f\u0434\u044f\u0442 \u0442\u0430\u043a:<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">import { cacheNames } from 'workbox-core'  const precacheCacheName = cacheNames.precache const runtimeCacheName = cacheNames.runtime const googleAnalyticsCacheName = cacheNames.googleAnalytics<\/code><\/pre>\n<p>  <\/p>\n<p>\u041a\u0430\u0436\u0434\u043e\u0435 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u0441\u043e\u0441\u0442\u043e\u0438\u0442 \u0438\u0437 \u0442\u0440\u0435\u0445 \u0447\u0430\u0441\u0442\u0435\u0439:<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">&lt;prefix&gt;-&lt;cacheId&gt;-&lt;suffix&gt;<\/code><\/pre>\n<p>  <\/p>\n<p>\u042d\u0442\u0438 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u044f \u043c\u043e\u0436\u043d\u043e \u043c\u0435\u043d\u044f\u0442\u044c \u043a\u0430\u043a \u0446\u0435\u043b\u0438\u043a\u043e\u043c, \u0442\u0430\u043a \u0438 \u043f\u043e \u0447\u0430\u0441\u0442\u044f\u043c:<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">import { setCacheNameDetails } from 'workbox-core'  setCacheNameDetails({   prefix: 'my-app',   suffix: 'v1' })<\/code><\/pre>\n<p>  <\/p>\n<p>\u0418\u043b\u0438 \u0442\u0430\u043a:<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">import { setCacheNameDetails } from 'workbox-core'  setCacheNameDetails({   prefix: 'my-app',   suffix: 'v1',   precache: 'custom-precache-name',   runtime: 'custom-runtime-name',   googleAnalytics: 'custom-google-analytics-name' })<\/code><\/pre>\n<p>  <\/p>\n<h3 id=\"kastomnye-nazvaniya-kesha-v-strategiyah\">\u041a\u0430\u0441\u0442\u043e\u043c\u043d\u044b\u0435 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u044f \u043a\u044d\u0448\u0430 \u0432 \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u044f\u0445<\/h3>\n<p>  <\/p>\n<p>\u041d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0447\u0430\u0441\u0442\u0438 <code>WB API<\/code> \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u044e\u0442 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0443 <code>cacheName<\/code> \u0441 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435\u043c \u043a\u044d\u0448\u0430. \u041a \u0442\u0430\u043a\u0438\u043c <code>API<\/code>, \u0432 \u0447\u0430\u0441\u0442\u043d\u043e\u0441\u0442\u0438, \u043e\u0442\u043d\u043e\u0441\u044f\u0442\u0441\u044f \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u0438. \u0412 \u0441\u043b\u0443\u0447\u0430\u0435 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 <code>cacheName<\/code>, \u043f\u0440\u0435\u0444\u0438\u043a\u0441 \u0438 \u0441\u0443\u0444\u0444\u0438\u043a\u0441 \u043d\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442\u0441\u044f. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0432\u043e\u0442 \u043a\u0430\u043a \u043c\u043e\u0436\u043d\u043e \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u0442\u044c \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u0434\u043b\u044f \u043a\u044d\u0448\u0430 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0439:<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">import { registerRoute } from 'workbox-routing' import { CacheFirst } from 'workbox-strategies'  registerRoute(   ({ request }) =&gt; request.destination === 'image',   new CacheFirst({     cacheName: 'my-image-cache'   }) )<\/code><\/pre>\n<p>  <\/p>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0431\u0443\u0434\u0443\u0442 \u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0442\u044c\u0441\u044f \u0432 \u043a\u044d\u0448 <code>my-image-cache<\/code>.<\/p>\n<p>  <\/p>\n<h3 id=\"nastroyki-zaprosov-v-strategiyah\">\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 \u0432 \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u044f\u0445<\/h3>\n<p>  <\/p>\n<p>\u041f\u0440\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0438 \u043a\u0430\u0441\u0442\u043e\u043c\u043d\u043e\u0439 \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u0438 \u0434\u043b\u044f \u043a\u044d\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u043c\u043e\u0436\u0435\u0442 \u043f\u043e\u0442\u0440\u0435\u0431\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0430\u0441\u043f\u0435\u043a\u0442\u043e\u0432 \u0438\u0441\u0445\u043e\u0434\u044f\u0449\u0438\u0445 \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0432 \u0437\u0430\u043f\u0440\u043e\u0441\u0435 \u043c\u043e\u0433\u0443\u0442 \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u043e\u0432\u0430\u0442\u044c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 \u0434\u043b\u044f \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u0438.<\/p>\n<p>  <\/p>\n<p>\u0414\u043b\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0442\u0430\u043a\u043e\u0433\u043e \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u044f \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043f\u0435\u0440\u0435\u0434\u0430\u0442\u044c \u0432 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440 \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u0438 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0443 <code>fetchOptions<\/code>, \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0443\u044e \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430\u043c <a href=\"https:\/\/developer.mozilla.org\/ru\/docs\/Web\/API\/WindowOrWorkerGlobalScope\/fetch#%D0%B0%D1%80%D0%B3%D1%83%D0%BC%D0%B5%D0%BD%D1%82%D1%8B\"><code>init<\/code><\/a> <code>Fetch API<\/code>. \u042d\u0442\u0438 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u0431\u0443\u0434\u0443\u0442 \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u0442\u044c\u0441\u044f \u0432 \u043e\u0442\u043d\u043e\u0448\u0435\u043d\u0438\u0438 \u0432\u0441\u0435\u0445 \u0438\u0441\u0445\u043e\u0434\u044f\u0449\u0438\u0445 \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u0434\u0430\u043d\u043d\u043e\u0439 \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u0435\u0439.<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">import { registerRoute } from 'workbox-routing' import { NetworkFirst } from 'workbox-strategies'  registerRoute(   ({ url }) =&gt; url.origin === 'https:\/\/third-party.example.com',   new NetworkFirst({     fetchOptions: {       credentials: 'include'     }   }) )<\/code><\/pre>\n<p>  <\/p>\n<h2 id=\"obrabotka-zaprosov-k-drugim-istochnikam\">\u041e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 \u043a \u0434\u0440\u0443\u0433\u0438\u043c \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u0430\u043c<\/h2>\n<p>  <\/p>\n<p>\u0417\u0430\u043f\u0440\u043e\u0441\u044b \u043a \u0434\u0440\u0443\u0433\u0438\u043c \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u0430\u043c \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u044e\u0442\u0441\u044f <code>WB<\/code> \u043e\u0441\u043e\u0431\u044b\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c.<\/p>\n<p>  <\/p>\n<h3 id=\"zaprosy-k-drugim-istochnikam-i-neprozrachnye-otvety\">\u0417\u0430\u043f\u0440\u043e\u0441\u044b \u043a \u0434\u0440\u0443\u0433\u0438\u043c \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u0430\u043c \u0438 \u043d\u0435\u043f\u0440\u043e\u0437\u0440\u0430\u0447\u043d\u044b\u0435 \u043e\u0442\u0432\u0435\u0442\u044b<\/h3>\n<p>  <\/p>\n<p>\u041e\u0434\u043d\u0438\u043c \u0438\u0437 \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0445 \u0437\u0430\u0449\u0438\u0442\u043d\u044b\u0445 \u043c\u0435\u0445\u0430\u043d\u0438\u0437\u043c\u043e\u0432, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u044b\u0445 \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u043e\u043c, \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0437\u0430\u043f\u0440\u0435\u0442 \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u043a \u0442\u0435\u043b\u0443 \u0438 \u0434\u0440\u0443\u0433\u0438\u043c \u0447\u0430\u0441\u0442\u044f\u043c \u043e\u0442\u0432\u0435\u0442\u0430, \u043f\u043e\u0441\u0442\u0443\u043f\u0438\u0432\u0448\u0435\u0433\u043e \u0438\u0437 \u0434\u0440\u0443\u0433\u043e\u0433\u043e \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u0430 \u0431\u0435\u0437 <a href=\"https:\/\/developer.mozilla.org\/ru\/docs\/Web\/HTTP\/CORS\"><code>CORS-\u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043a\u043e\u0432<\/code><\/a>. \u0422\u0430\u043a\u0438\u0435 \u043e\u0442\u0432\u0435\u0442\u044b \u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f &quot;\u043d\u0435\u043f\u0440\u043e\u0437\u0440\u0430\u0447\u043d\u044b\u043c\u0438&quot; (opaque). \u0421\u0412 \u0432 \u044d\u0442\u043e\u043c \u043e\u0442\u043d\u043e\u0448\u0435\u043d\u0438\u0438 \u043d\u0435 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435\u043c.<\/p>\n<p>  <\/p>\n<h3 id=\"ne-zabyvayte-vklyuchat-rezhim-cors\">\u041d\u0435 \u0437\u0430\u0431\u044b\u0432\u0430\u0439\u0442\u0435 \u0432\u043a\u043b\u044e\u0447\u0430\u0442\u044c \u0440\u0435\u0436\u0438\u043c <code>CORS<\/code><\/h3>\n<p>  <\/p>\n<p>\u0415\u0441\u043b\u0438 \u0432\u044b \u0437\u0430\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0435\u0442\u0435 \u0440\u0435\u0441\u0443\u0440\u0441\u044b \u0441 \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u0430, \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u044e\u0449\u0435\u0433\u043e <code>CORS<\/code>, \u043d\u043e \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442\u0435 \u043d\u0435\u043f\u0440\u043e\u0437\u0440\u0430\u0447\u043d\u044b\u0435 \u043e\u0442\u0432\u0435\u0442\u044b, \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e, \u0432\u044b \u043d\u0435\u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e \u0438\u0445 \u0437\u0430\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0435\u0442\u0435.<\/p>\n<p>  <\/p>\n<p>\u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 <code>HTML<\/code> \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u0442 \u0437\u0430\u043f\u0440\u043e\u0441\u044b, \u043f\u0440\u0438\u0432\u043e\u0434\u044f\u0449\u0438\u0435 \u043a \u043d\u0435\u043f\u0440\u043e\u0437\u0440\u0430\u0447\u043d\u044b\u043c \u043e\u0442\u0432\u0435\u0442\u0430\u043c, \u0434\u0430\u0436\u0435 \u0435\u0441\u043b\u0438 <code>example.com<\/code> \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 <code>CORS<\/code>:<\/p>\n<p>  <\/p>\n<pre><code class=\"html\">&lt;link rel=&quot;stylesheet&quot; href=&quot;https:\/\/example.com\/path\/to\/style.css&quot; \/&gt; &lt;img src=&quot;https:\/\/example.com\/path\/to\/image.png&quot; \/&gt;<\/code><\/pre>\n<p>  <\/p>\n<p>\u0412 \u0434\u0430\u043d\u043d\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435, \u0434\u043b\u044f \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432, \u0432 \u043e\u0442\u0432\u0435\u0442 \u043d\u0430 \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u044e\u0442\u0441\u044f \u043f\u0440\u043e\u0437\u0440\u0430\u0447\u043d\u044b\u0435 \u043e\u0442\u0432\u0435\u0442\u044b, \u0441\u043b\u0435\u0434\u0443\u0435\u0442 \u0432\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u0440\u0435\u0436\u0438\u043c <code>CORS<\/code> \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u0430 <code>crossorigin<\/code>:<\/p>\n<p>  <\/p>\n<pre><code class=\"html\">&lt;link   crossorigin=&quot;anonymous&quot;   rel=&quot;stylesheet&quot;   href=&quot;https:\/\/example.com\/path\/to\/style.css&quot; \/&gt; &lt;img crossorigin=&quot;anonymous&quot; src=&quot;https:\/\/example.com\/path\/to\/image.png&quot; \/&gt;<\/code><\/pre>\n<p>  <\/p>\n<h3 id=\"opasnost-keshirovaniya-neprozrachnyh-otvetov\">\u041e\u043f\u0430\u0441\u043d\u043e\u0441\u0442\u044c \u043a\u044d\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u043d\u0435\u043f\u0440\u043e\u0437\u0440\u0430\u0447\u043d\u044b\u0445 \u043e\u0442\u0432\u0435\u0442\u043e\u0432<\/h3>\n<p>  <\/p>\n<p>\u041e\u0431\u044b\u0447\u043d\u043e, <code>WB<\/code> \u043d\u0435 \u043a\u044d\u0448\u0438\u0440\u0443\u0435\u0442 \u043d\u0435\u043f\u0440\u043e\u0437\u0440\u0430\u0447\u043d\u044b\u0435 \u043e\u0442\u0432\u0435\u0442\u044b. \u041f\u0440\u0438\u0447\u0438\u043d\u0430 \u044d\u0442\u043e\u0433\u043e \u0437\u0430\u043a\u043b\u044e\u0447\u0430\u0435\u0442\u0441\u044f \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u0442\u0430\u043a\u0438\u0435 \u043e\u0442\u0432\u0435\u0442\u044b \u043c\u043e\u0433\u0443\u0442 \u043f\u0440\u0438\u0432\u0435\u0441\u0442\u0438 \u043a \u043f\u043b\u043e\u0445\u043e\u043c\u0443 &quot;\u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044e&quot; \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f. \u041f\u0440\u0435\u0434\u043f\u043e\u043b\u043e\u0436\u0438\u043c, \u0447\u0442\u043e \u043c\u044b \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u043b\u0438 \u0442\u0430\u043a\u043e\u0439 \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0438\u0437\u0430\u0442\u043e\u0440:<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">import { registerRoute } from 'workbox-routing' import { CacheFirst } from 'workbox-strategies'  registerRoute('https:\/\/cdn.google.com\/example-script.min.js', new CacheFirst())<\/code><\/pre>\n<p>  <\/p>\n<p>\u0412 \u0434\u0430\u043d\u043d\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435, \u043b\u044e\u0431\u043e\u0439 \u043e\u0442\u0432\u0435\u0442 \u0431\u0443\u0434\u0435\u0442 \u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0442\u044c\u0441\u044f \u0432 \u043a\u044d\u0448 \u0438 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0442\u044c\u0441\u044f \u0432 \u043e\u0442\u0432\u0435\u0442 \u043d\u0430 \u0437\u0430\u043f\u0440\u043e\u0441. \u0421\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u0435 \u0438 \u0432\u043e\u0437\u0432\u0440\u0430\u0442 \u043d\u0435\u043f\u0440\u043e\u0437\u0440\u0430\u0447\u043d\u043e\u0433\u043e \u043e\u0442\u0432\u0435\u0442\u0430 \u043c\u043e\u0433\u0443\u0442 \u043f\u0440\u0438\u0432\u0435\u0441\u0442\u0438 \u043a \u043f\u043e\u043b\u043e\u043c\u043a\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f.<\/p>\n<p>  <\/p>\n<p>\u0422\u0435\u043c \u043d\u0435 \u043c\u0435\u043d\u0435\u0435, \u0434\u0430\u043d\u043d\u044b\u0439 \u043f\u043e\u0434\u0445\u043e\u0434 \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0441 \u0442\u0430\u043a\u0438\u043c\u0438 \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u044f\u043c\u0438 \u043a\u0430\u043a <code>StaleWhileRevalidate<\/code> \u0438 <code>NetworkFirst<\/code>, \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u0432 \u044d\u0442\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u0432\u0440\u0435\u043c\u044f \u0436\u0438\u0437\u043d\u0438 \u043f\u043b\u043e\u0445\u043e\u0433\u043e \u043e\u0442\u0432\u0435\u0442\u0430 \u0431\u0443\u0434\u0435\u0442 \u043d\u0435\u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u043c \u0437\u0430 \u0441\u0447\u0435\u0442 \u0440\u0435\u0433\u0443\u043b\u044f\u0440\u043d\u043e\u0433\u043e \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f \u043a\u044d\u0448\u0430.<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">import { registerRoute } from 'workbox-routing' import { NetworkFirst, StaleWhileRevalidate } from 'workbox-strategies'  registerRoute(   'https:\/\/cdn.google.com\/example-script.min.js',   new NetworkFirst() )  \/\/ \u0438\u043b\u0438 registerRoute(   'https:\/\/cdn.google.com\/example-script.min.js',   new StaleWhileRevalidate() )<\/code><\/pre>\n<p>  <\/p>\n<p>\u041f\u0440\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0438 \u0434\u0440\u0443\u0433\u043e\u0439 \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u0438 \u0438 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0438 \u043d\u0435\u043f\u0440\u043e\u0437\u0440\u0430\u0447\u043d\u043e\u0433\u043e \u043e\u0442\u0432\u0435\u0442\u0430 <code>WB<\/code> \u0432\u044b\u0432\u0435\u0434\u0435\u0442 \u0432 \u043a\u043e\u043d\u0441\u043e\u043b\u044c \u043f\u0440\u0435\u0434\u0443\u043f\u0440\u0435\u0436\u0434\u0435\u043d\u0438\u0435 \u043e \u0442\u043e\u043c, \u0447\u0442\u043e \u043e\u0442\u0432\u0435\u0442 \u043d\u0435 \u043a\u044d\u0448\u0438\u0440\u043e\u0432\u0430\u043d.<\/p>\n<p>  <\/p>\n<h3 id=\"prinuditelnoe-keshirovanie-neprozrachnyh-otvetov\">\u041f\u0440\u0438\u043d\u0443\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0435 \u043a\u044d\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043d\u0435\u043f\u0440\u043e\u0437\u0440\u0430\u0447\u043d\u044b\u0445 \u043e\u0442\u0432\u0435\u0442\u043e\u0432<\/h3>\n<p>  <\/p>\n<p>\u041d\u0435\u043f\u0440\u043e\u0437\u0440\u0430\u0447\u043d\u044b\u0435 \u043e\u0442\u0432\u0435\u0442\u044b \u043c\u043e\u0433\u0443\u0442 \u043f\u0440\u0438\u043d\u0443\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0442\u044c\u0441\u044f \u0432 \u043a\u044d\u0448 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043f\u043b\u0430\u0433\u0438\u043d\u043e\u0432, \u0442\u0430\u043a\u0438\u0445 \u043a\u0430\u043a <code>workbox-cacheable-response<\/code>:<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">import { registerRoute } from 'workbox-routing' import { NetworkFirst, StaleWhileRevalidate } from 'workbox-strategies' import { CacheableResponsePlugin } from 'workbox-cacheable-response'  registerRoute(   'https:\/\/cdn.google.com\/example-script.min.js',   new CacheFirst({     plugins: [       new CacheableResponsePlugin({         statuses: [0, 200]       })     ]   }) )<\/code><\/pre>\n<p>  <\/p>\n<h2 id=\"ispolzovanie-plaginov\">\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u043f\u043b\u0430\u0433\u0438\u043d\u043e\u0432<\/h2>\n<p>  <\/p>\n<p>\u041f\u043b\u0430\u0433\u0438\u043d\u044b \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0442 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0442\u044c \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0435 \u043f\u043e\u0432\u0435\u0434\u0435\u043d\u0438\u0435, \u0441\u0432\u044f\u0437\u0430\u043d\u043d\u043e\u0435 \u0441 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u043e\u0439 \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 \u0438\u043b\u0438 \u043e\u0442\u0432\u0435\u0442\u043e\u0432, \u0432 \u0442\u0435\u0447\u0435\u043d\u0438\u0435 \u0436\u0438\u0437\u043d\u0435\u043d\u043d\u043e\u0433\u043e \u0446\u0438\u043a\u043b\u0430 \u0437\u0430\u043f\u0440\u043e\u0441\u0430.<\/p>\n<p>  <\/p>\n<h3 id=\"plaginy-predostavlyaemye-wb\">\u041f\u043b\u0430\u0433\u0438\u043d\u044b, \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u043c\u044b\u0435 <code>WB<\/code><\/h3>\n<p>  <\/p>\n<p><code>WB<\/code> \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u043f\u043b\u0430\u0433\u0438\u043d\u044b:<\/p>\n<p>  <\/p>\n<ul>\n<li><code>BackgroundSyncPlugin<\/code> \u2014 \u043f\u0440\u0438 \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0438\u0438 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u043a \u0441\u0435\u0442\u0438 \u0437\u0430\u043f\u0440\u043e\u0441 \u043f\u043e\u043c\u0435\u0449\u0430\u0435\u0442\u0441\u044f \u0432 \u043e\u0447\u0435\u0440\u0435\u0434\u044c \u0444\u043e\u043d\u043e\u0432\u043e\u0439 \u0441\u0438\u043d\u0445\u0440\u043e\u043d\u0438\u0437\u0430\u0446\u0438\u0438 (background sync queue) \u0438 \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u043e \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043f\u0440\u0438 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u043c \u0432\u043e\u0437\u043d\u0438\u043a\u043d\u043e\u0432\u0435\u043d\u0438\u0438 \u0441\u043e\u0431\u044b\u0442\u0438\u044f <code>sync<\/code><\/li>\n<li><code>BroadcastUpdatePlugin<\/code> \u2014 \u043f\u0440\u0438 \u043b\u044e\u0431\u043e\u043c \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0438 \u043a\u044d\u0448\u0430 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f (dispatch) \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0432 <code>BroadcastChannel<\/code> \u0438\u043b\u0438 \u0447\u0435\u0440\u0435\u0437 <code>postMessage()<\/code><\/li>\n<li><code>CacheableResponsePlugin<\/code> \u2014 \u043a\u044d\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u0442\u0435\u0445 \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0442 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u043d\u044b\u043c \u043a\u0440\u0438\u0442\u0435\u0440\u0438\u044f\u043c<\/li>\n<li><code>ExpirationPlugin<\/code> \u2014 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u0430 \u0438\u043b\u0438 \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0432\u043e\u0437\u0440\u0430\u0441\u0442\u0430 \u0437\u0430\u043f\u0438\u0441\u0435\u0439 \u0432 \u043a\u044d\u0448\u0435<\/li>\n<li><code>RangeRequestsPlugin<\/code> \u2014 \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0430 \u043e\u0442\u0432\u0435\u0442\u043e\u0432 \u043d\u0430 \u0437\u0430\u043f\u0440\u043e\u0441\u044b, \u0432\u043a\u043b\u044e\u0447\u0430\u044e\u0449\u0438\u0435 \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043e\u043a <code>Range<\/code> (\u0447\u0430\u0441\u0442\u0438\u0447\u043d\u044b\u0439 \u043a\u043e\u043d\u0442\u0435\u043d\u0442 \u0438\u0437 \u043a\u044d\u0448\u0430)<\/li>\n<\/ul>\n<p>  <\/p>\n<pre><code class=\"plaintext\">import { registerRoute } from 'workbox-routing' import { CacheFirst } from 'workbox-strategies' import { ExpirationPlugin } from 'workbox-expiration'  registerRoute(   ({ request }) =&gt; request.destination === 'image',   new CacheFirst({     cacheName: 'images',     plugins: [       new ExpirationPlugin({         maxEntries: 60,         maxAgeSeconds: 30 * 24 * 60 * 60 \/\/ 30 \u0434\u043d\u0435\u0439       })     ]   }) )<\/code><\/pre>\n<p>  <\/p>\n<h3 id=\"kastomnye-plaginy\">\u041a\u0430\u0441\u0442\u043e\u043c\u043d\u044b\u0435 \u043f\u043b\u0430\u0433\u0438\u043d\u044b<\/h3>\n<p>  <\/p>\n<p>\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u0438\u0439 \u043f\u043b\u0430\u0433\u0438\u043d \u2014 \u044d\u0442\u043e \u043e\u0431\u044a\u0435\u043a\u0442, \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0449\u0438\u0439 \u043e\u0434\u0438\u043d \u0438\u0437 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0445 \u043c\u0435\u0442\u043e\u0434\u043e\u0432:<\/p>\n<p>  <\/p>\n<ul>\n<li><code>cacheWillUpdate<\/code>: \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043f\u0435\u0440\u0435\u0434 \u0442\u0435\u043c, \u043a\u0430\u043a <code>Response<\/code> \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0434\u043b\u044f \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f \u043a\u044d\u0448\u0430. \u041e\u043d \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0438\u0437\u043c\u0435\u043d\u044f\u0442\u044c \u043e\u0442\u0432\u0435\u0442 \u043f\u0435\u0440\u0435\u0434 \u0435\u0433\u043e \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435\u043c \u0432 \u043a\u044d\u0448 \u0438\u043b\u0438 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0442\u044c <code>null<\/code> \u0434\u043b\u044f \u043f\u0440\u0435\u0434\u043e\u0442\u0432\u0440\u0430\u0449\u0435\u043d\u0438\u044f \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f<\/li>\n<li><code>cacheDidUpdate<\/code>: \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043f\u0435\u0440\u0435\u0434 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435\u043c \u043d\u043e\u0432\u043e\u0439 \u0437\u0430\u043f\u0438\u0441\u0438 \u0432 \u043a\u044d\u0448 \u0438\u043b\u0438 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435\u043c \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0435\u0439 \u0437\u0430\u043f\u0438\u0441\u0438. \u041c\u043e\u0436\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0434\u043b\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u043a\u0430\u043a\u0438\u0445-\u043b\u0438\u0431\u043e \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439 \u043f\u043e\u0441\u043b\u0435 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f \u043a\u044d\u0448\u0430<\/li>\n<li><code>cacheKeyWillBeUsed<\/code>: \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043f\u0435\u0440\u0435\u0434 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043a\u043b\u044e\u0447\u0430 \u0434\u043b\u044f \u043a\u044d\u0448\u0430, \u043a\u0430\u043a \u0434\u043b\u044f \u043f\u043e\u0438\u0441\u043a\u0430 \u043a\u044d\u0448\u0430 (\u0432 \u0440\u0435\u0436\u0438\u043c\u0435 <code>read<\/code>), \u0442\u0430\u043a \u0438 \u0434\u043b\u044f \u0437\u0430\u043f\u0438\u0441\u0438 \u0432 \u043a\u044d\u0448 (\u0432 \u0440\u0435\u0436\u0438\u043c\u0435 <code>write<\/code>). \u041c\u043e\u0436\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0434\u043b\u044f \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0438\u0441\u0438 \u0438\u043b\u0438 \u043d\u043e\u0440\u043c\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 <code>URL<\/code> \u043f\u0435\u0440\u0435\u0434 \u0438\u0445 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u0434\u043b\u044f \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u043a \u043a\u044d\u0448\u0443<\/li>\n<li><code>cacheResponseWillBeUsed<\/code>: \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043f\u0435\u0440\u0435\u0434 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u043e\u0442\u0432\u0435\u0442\u0430 \u0438\u0437 \u043a\u044d\u0448\u0430. \u041f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0442\u044c \u043e\u0442\u0432\u0435\u0442 \u0438 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0442\u044c <code>null<\/code> \u0438\u043b\u0438 \u0434\u0440\u0443\u0433\u043e\u0439 \u043e\u0442\u0432\u0435\u0442<\/li>\n<li><code>requestWillFetch<\/code>: \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043f\u0435\u0440\u0435\u0434 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435\u043c \u0441\u0435\u0442\u0435\u0432\u043e\u0433\u043e \u0437\u0430\u043f\u0440\u043e\u0441\u0430. \u041f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0438\u0437\u043c\u0435\u043d\u044f\u0442\u044c <code>Request<\/code><\/li>\n<li><code>fetchDidFail<\/code>: \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043f\u0440\u0438 \u043f\u0440\u043e\u0432\u0430\u043b\u0435 \u0437\u0430\u043f\u0440\u043e\u0441\u0430, \u0447\u0430\u0449\u0435 \u0432\u0441\u0435\u0433\u043e \u0441\u0432\u044f\u0437\u0430\u043d\u043d\u044b\u043c \u0441 <code>NetworkError<\/code>. \u041e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435, \u0447\u0442\u043e \u0434\u0430\u043d\u043d\u044b\u0439 \u043c\u0435\u0442\u043e\u0434 \u043d\u0435 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043f\u0440\u0438 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0438 \u043e\u0448\u0438\u0431\u043a\u0438, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, <code>404 Not Found<\/code><\/li>\n<li><code>fetchDidSucceed<\/code>: \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043f\u0440\u0438 \u0443\u0441\u043f\u0435\u0448\u043d\u043e\u043c \u0437\u0430\u043f\u0440\u043e\u0441\u0435, \u043d\u0435\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e \u043e\u0442 \u0441\u0442\u0430\u0442\u0443\u0441\u0430 \u043e\u0442\u0432\u0435\u0442\u0430<\/li>\n<li><code>handlerWillStart<\/code>: \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043f\u0435\u0440\u0435\u0434 \u0437\u0430\u043f\u0443\u0441\u043a\u043e\u043c \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0430 \u043e\u0442\u0432\u0435\u0442\u0430. \u041c\u043e\u0436\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0434\u043b\u044f \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438 \u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0430<\/li>\n<li><code>handlerWillRespond<\/code>: \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043f\u0435\u0440\u0435\u0434 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0435\u043d\u0438\u0435\u043c \u043e\u0442\u0432\u0435\u0442\u0430 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u043e\u043c \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u0438. \u041c\u043e\u0436\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0434\u043b\u044f \u043c\u043e\u0434\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 \u043e\u0442\u0432\u0435\u0442\u0430, \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c\u043e\u0433\u043e \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u043e\u043c<\/li>\n<li><code>handlerDidRespond<\/code>: \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043f\u043e\u0441\u043b\u0435 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0435\u043d\u0438\u044f \u043e\u0442\u0432\u0435\u0442\u0430 \u043c\u0435\u0442\u043e\u0434\u043e\u043c <code>handle()<\/code>. \u041c\u043e\u0436\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0434\u043b\u044f \u0437\u0430\u043f\u0438\u0441\u0438 \u043b\u044e\u0431\u044b\u0445 \u0434\u0435\u0442\u0430\u043b\u0435\u0439 \u043e\u0442\u0432\u0435\u0442\u0430, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043f\u043e\u0441\u043b\u0435 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439, \u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0434\u0435\u043d\u043d\u044b\u0445 \u0441 \u043d\u0438\u043c \u043f\u043b\u0430\u0433\u0438\u043d\u0430\u043c\u0438<\/li>\n<li><code>handleDidComplete<\/code>: \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043f\u043e\u0441\u043b\u0435 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0432 <code>event<\/code> \u0432\u0441\u0435\u0445 <a href=\"https:\/\/w3c.github.io\/ServiceWorker\/#extendableevent-extend-lifetime-promises\">&quot;\u043f\u0440\u043e\u043c\u0438\u0441\u043e\u0432 \u0434\u043b\u044f \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u044f \u0436\u0438\u0437\u043d\u0435\u043d\u043d\u043e\u0433\u043e \u0446\u0438\u043a\u043b\u0430&quot;<\/a>. \u041c\u043e\u0436\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0434\u043b\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0434\u0430\u043d\u043d\u044b\u0445, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0441\u0442\u0430\u043d\u043e\u0432\u044f\u0442\u0441\u044f \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u043c\u0438 \u043f\u043e\u0441\u043b\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0441\u0432\u043e\u0438\u0445 \u0437\u0430\u0434\u0430\u0447 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u043e\u043c (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043a\u044d\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0441\u0442\u0430\u0442\u0443\u0441\u0430 \u043e\u0431\u0440\u0430\u0449\u0435\u043d\u0438\u0439, \u0437\u0430\u0434\u0435\u0440\u0436\u043a\u0430 \u043a\u044d\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f, \u0437\u0430\u0434\u0435\u0440\u0436\u043a\u0430 \u0441\u0435\u0442\u0435\u0432\u043e\u0433\u043e \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u0438 \u0442.\u0434.)<\/li>\n<li><code>handleDidError<\/code>: \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f, \u043a\u043e\u0433\u0434\u0430 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u043d\u0435 \u043c\u043e\u0436\u0435\u0442 \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u0432\u0430\u043b\u0438\u0434\u043d\u044b\u0439 \u043e\u0442\u0432\u0435\u0442 \u043d\u0438 \u0438\u0437 \u043a\u044d\u0448\u0430, \u043d\u0438 \u0438\u0437 \u0441\u0435\u0442\u0438. \u041c\u043e\u0436\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0434\u043b\u044f \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0440\u0435\u0437\u0435\u0440\u0432\u043d\u043e\u0433\u043e \u043a\u043e\u043d\u0442\u0435\u043d\u0442\u0430 \u043f\u0440\u0438 \u0432\u043e\u0437\u043d\u0438\u043a\u043d\u043e\u0432\u0435\u043d\u0438\u0438 \u0441\u0435\u0442\u0435\u0432\u043e\u0439 \u043e\u0448\u0438\u0431\u043a\u0438<\/li>\n<\/ul>\n<p>  <\/p>\n<p>\u0412\u0441\u0435 \u044d\u0442\u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0432\u044b\u0437\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u0441 \u043a\u043b\u044e\u0447\u0435\u0432\u044b\u043c \u0441\u043b\u043e\u0432\u043e\u043c <code>await<\/code> \u043f\u0440\u0438 \u0434\u043e\u0441\u0442\u0438\u0436\u0435\u043d\u0438\u0438 \u043a\u044d\u0448\u0435\u043c (\u0438\u043b\u0438 \u0441\u043e\u0431\u044b\u0442\u0438\u0435\u043c <code>fetch<\/code>) \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u044c\u043d\u043e\u0439 \u0442\u043e\u0447\u043a\u0438.<\/p>\n<p>  <\/p>\n<p>\u0412\u043e\u0442 \u043a\u0430\u043a \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u044d\u0442\u0438\u0445 \u043a\u043e\u043b\u0431\u044d\u043a\u043e\u0432:<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">const myPlugin = {   cacheWillUpdate: async ({ request, response, event, state }) =&gt; {     \/\/ \u0412\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c `response`, \u0434\u0440\u0443\u0433\u043e\u0439 \u043e\u0431\u044a\u0435\u043a\u0442 `Response` \u0438\u043b\u0438 `null`     return response   },   cacheDidUpdate: async ({     cacheName,     request,     oldResponse,     newResponse,     event,     state   }) =&gt; {     \/\/ \u041d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c.     \/\/ \u041e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435 `newResponse.bodyUsed` \u0438\u043c\u0435\u0435\u0442 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 `true` \u043f\u0440\u0438 \u0432\u044b\u0437\u043e\u0432\u0435.     \/\/ \u042d\u0442\u043e \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442, \u0447\u0442\u043e \u0442\u0435\u043b\u043e \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u0443\u0436\u0435 \u043f\u0440\u043e\u0447\u0438\u0442\u0430\u043d\u043e. \u0415\u0441\u043b\u0438 \u0432\u0430\u043c \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0434\u043e\u0441\u0442\u0443\u043f     \/\/ \u043a \u0442\u0435\u043b\u0443 \u0441\u0432\u0435\u0436\u0435\u0433\u043e \u043e\u0442\u0432\u0435\u0442\u0430:     \/\/ const freshResponse = await caches.match(request, { cacheName })   },   cacheKeyWillBeUsed: async ({ request, mode, params, event, state }) =&gt; {     \/\/ `request` - \u044d\u0442\u043e \u043e\u0431\u044a\u0435\u043a\u0442 `Request`, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043a\u043b\u044e\u0447\u0430 \u043a\u044d\u0448\u0430.     \/\/ `mode` \u043c\u043e\u0436\u0435\u0442 \u0438\u043c\u0435\u0442\u044c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 'read' \u0438\u043b\u0438 'write'.     \/\/ \u0412\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c \u0441\u0442\u0440\u043e\u043a\u0443 \u0438\u043b\u0438 `Request`, \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u043e `url` \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u0431\u0443\u0434\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u043e \u043a\u0430\u043a \u043a\u043b\u044e\u0447 \u043a\u044d\u0448\u0430.     \/\/ \u0412\u043e\u0437\u0432\u0440\u0430\u0442 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b\u044c\u043d\u043e\u0433\u043e `request` \u043b\u0438\u0448\u0430\u0435\u0442 \u0441\u043c\u044b\u0441\u043b\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u044d\u0442\u043e\u0433\u043e \u043a\u043e\u043b\u0431\u044d\u043a\u0430     return request   },   cachedResponseWillBeUsed: async ({     cacheName,     request,     matchOptions,     cachedResponse,     event,     state,   }) =&gt; {     \/\/ \u0412\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c `cachedResponse`, \u0434\u0440\u0443\u0433\u043e\u0439 \u043e\u0431\u044a\u0435\u043a\u0442 `Response` \u0438\u043b\u0438 `null`     return cachedResponse   },   requestWillFetch: async ({ request, event, state }) =&gt; {     \/\/ \u0412\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c `request` \u0438\u043b\u0438 \u0434\u0440\u0443\u0433\u043e\u0439 \u043e\u0431\u044a\u0435\u043a\u0442 `Request`     return request   },   fetchDidFail: async ({ originalRequest, request, error, event, state }) =&gt; {     \/\/ \u041d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c.     \/\/ \u041e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435: `originalRequest` - \u044d\u0442\u043e \u0437\u0430\u043f\u0440\u043e\u0441 \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0430, `request` - \u044d\u0442\u043e     \/\/ \u0437\u0430\u043f\u0440\u043e\u0441, \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0430\u043d\u043d\u044b\u0439 \u043f\u043b\u0430\u0433\u0438\u043d\u0430\u043c\u0438 \u0432     \/\/ \u043a\u043e\u043b\u0431\u044d\u043a\u0430\u0445 `requestWillFetch`, \u0430 `error` - \u044d\u0442\u043e \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435, \u0432\u044b\u0437\u0432\u0430\u0432\u0448\u0435\u0435     \/\/ \u043f\u0440\u043e\u0432\u0430\u043b `fetch()`   },   fetchDidSucceed: async ({ request, response, event, state }) =&gt; {     \/\/ \u0412\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c `response` \u0434\u043b\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0441\u0435\u0442\u0435\u0432\u043e\u0433\u043e \u043e\u0442\u0432\u0435\u0442\u0430 \u043a\u0430\u043a \u0435\u0441\u0442\u044c \u0438\u043b\u0438 \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u0438 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c \u043d\u043e\u0432\u044b\u0439 \u043e\u0431\u044a\u0435\u043a\u0442 `Response`     return response   },   handlerWillStart: async ({ request, event, state }) =&gt; {     \/\/ \u041d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c.     \/\/ \u0417\u0434\u0435\u0441\u044c \u043c\u043e\u0436\u043d\u043e \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0430   },   handlerWillRespond: async ({ request, response, event, state }) =&gt; {     \/\/ \u0412\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c `response` \u0438\u043b\u0438 \u0434\u0440\u0443\u0433\u043e\u0439 \u043e\u0431\u044a\u0435\u043a\u0442 `Response`     return response   },   handlerDidRespond: async ({ request, response, event, state }) =&gt; {     \/\/ \u041d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c.     \/\/ \u0417\u0434\u0435\u0441\u044c \u043c\u043e\u0436\u043d\u043e \u0437\u0430\u0444\u0438\u043a\u0441\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043a\u043e\u043d\u0435\u0447\u043d\u044b\u0439 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442   },   handlerDidComplete: async ({ request, response, error, event, state }) =&gt; {     \/\/ \u041d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c.     \/\/ \u0417\u0434\u0435\u0441\u044c \u043c\u043e\u0436\u043d\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0441 \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u043c\u0438 \u0434\u0430\u043d\u043d\u044b\u043c\u0438   },   handlerDidError: async ({ request, event, error, state }) =&gt; {     \/\/ \u0412\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c `response` \u0438\u043b\u0438 \u0434\u0440\u0443\u0433\u043e\u0439 \u043e\u0431\u044a\u0435\u043a\u0442 `Response` (\u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043f\u043e\u0434\u0441\u0442\u0440\u0430\u0445\u043e\u0432\u043a\u0438), \u0438\u043b\u0438 `null`     return response   } }<\/code><\/pre>\n<p>  <\/p>\n<p>\u041a\u0430\u043a \u043f\u0440\u0430\u0432\u0438\u043b\u043e, \u043e\u0431\u044a\u0435\u043a\u0442 <code>event<\/code>, \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0435\u043c\u044b\u0439 \u0432 \u043a\u043e\u043b\u0431\u044d\u043a \u2014 \u044d\u0442\u043e \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u0435 \u0441\u043e\u0431\u044b\u0442\u0438\u0435, \u0432\u044b\u0437\u0432\u0430\u0432\u0448\u0435\u0435 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044e <code>fetch<\/code> \u0438\u043b\u0438 <code>cache<\/code>. \u0422\u0435\u043c \u043d\u0435 \u043c\u0435\u043d\u0435\u0435, \u0432\u0441\u0435\u0433\u0434\u0430 \u0441\u043b\u0435\u0434\u0443\u0435\u0442 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0442\u044c \u043d\u0430\u043b\u0438\u0447\u0438\u0435 \u0434\u0430\u043d\u043d\u043e\u0433\u043e \u043e\u0431\u044a\u0435\u043a\u0442\u0430 \u043f\u0435\u0440\u0435\u0434 \u0435\u0433\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c. \u041f\u0440\u0438 \u0432\u044b\u0437\u043e\u0432\u0435 \u043c\u0435\u0442\u043e\u0434\u0430 <code>handle()<\/code> \u0432 \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u0438 <code>event<\/code>, \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0435\u043c\u044b\u0439 \u0432 \u043d\u0435\u0433\u043e, \u0431\u0443\u0434\u0435\u0442 \u043f\u0435\u0440\u0435\u0434\u0430\u043d \u0432 \u043a\u043e\u043b\u0431\u044d\u043a\u0438 \u043f\u043b\u0430\u0433\u0438\u043d\u043e\u0432.<\/p>\n<p>  <\/p>\n<p>\u0412\u0441\u0435 \u043a\u043e\u043b\u0431\u044d\u043a\u0438 \u0442\u0430\u043a\u0436\u0435 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u044e\u0442 \u043e\u0431\u044a\u0435\u043a\u0442 <code>state<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0443\u043d\u0438\u043a\u0430\u043b\u044c\u043d\u044b\u043c \u043f\u043e \u043e\u0442\u043d\u043e\u0448\u0435\u043d\u0438\u044e \u043a \u043e\u0431\u044a\u0435\u043a\u0442\u0443 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u0433\u043e \u043f\u043b\u0430\u0433\u0438\u043d\u0430 \u0438 \u0432\u044b\u0437\u043e\u0432\u0443 \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u0438. \u042d\u0442\u043e \u0434\u0435\u043b\u0430\u0435\u0442 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u044b\u043c \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e \u043f\u043b\u0430\u0433\u0438\u043d\u043e\u0432, \u0433\u0434\u0435 \u043e\u0434\u0438\u043d \u043a\u043e\u043b\u0431\u044d\u043a \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u0434\u0430\u043d\u043d\u044b\u0445, \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u0445 \u043e\u0442 \u0434\u0440\u0443\u0433\u043e\u0433\u043e \u043a\u043e\u043b\u0431\u044d\u043a\u0430 \u0432 \u0442\u043e\u043c \u0436\u0435 \u043f\u043b\u0430\u0433\u0438\u043d\u0435 (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0435 \u0434\u0435\u043b\u044c\u0442\u044b \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u043c\u0435\u0436\u0434\u0443 \u0437\u0430\u043f\u0443\u0441\u043a\u043e\u043c <code>requestWillFetch()<\/code> \u0438 <code>fetchDidSucceed()<\/code> \u0438\u043b\u0438 <code>fetchDidFail()<\/code>).<\/p>\n<p>  <\/p>\n<h2 id=\"kvota-hranilischa\">\u041a\u0432\u043e\u0442\u0430 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0430<\/h2>\n<p>  <\/p>\n<p>\u041a\u0430\u0436\u0434\u044b\u0439 \u0431\u0440\u0430\u0443\u0437\u0435\u0440 \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u0442 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u044b\u0439 \u043b\u0438\u043c\u0438\u0442 \u043e\u0431\u044a\u0435\u043c\u0430 \u043f\u0430\u043c\u044f\u0442\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u043e\u0436\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435\u043c. \u0414\u0430\u043d\u043d\u044b\u0439 \u043b\u0438\u043c\u0438\u0442 \u0437\u0430\u0432\u0438\u0441\u0438\u0442 \u043e\u0442 \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0430. \u041e\u0431\u044a\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u043e\u0439 \u0438 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u043e\u0439 \u043f\u0430\u043c\u044f\u0442\u0438 \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e <code>navigator.storage.estimate()<\/code>. <code>WB<\/code> \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043d\u0430\u0441\u0442\u0440\u043e\u0438\u0442\u044c \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0443\u044e \u043e\u0447\u0438\u0441\u0442\u043a\u0443 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0430 \u043f\u0440\u0438 \u0434\u043e\u0441\u0442\u0438\u0436\u0435\u043d\u0438\u0438 \u043a\u0432\u043e\u0442\u044b (storage quota).<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">import { registerRoute } from 'workbox-routing' import { CacheFirst } from 'workbox-strategies' import { ExpirationPlugin } from 'workbox-expiration'  registerRoute(   ({ request }) =&gt; request.destination === 'image',   \/\/ \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u044e &quot;\u0441\u043d\u0430\u0447\u0430\u043b\u0430 \u043a\u044d\u0448&quot; \u0441\u043e \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c\u0438 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430\u043c\u0438   new CacheFirst({     \/\/ \u041d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u043a\u044d\u0448\u0430     cacheName: 'images',     plugins: [       new ExpirationPlugin({         \/\/ \u041c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0437\u0430\u043f\u0438\u0441\u0435\u0439 \u0432 \u043a\u044d\u0448\u0435 (\u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u043c\u044b\u0445 \u0444\u0430\u0439\u043b\u043e\u0432)         maxEntries: 50,         \/\/ \u0421\u0440\u043e\u043a \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0444\u0430\u0439\u043b\u043e\u0432 \u0432 \u043a\u044d\u0448\u0435         maxAgeSeconds: 30 * 24 * 60 * 60,         \/\/ \u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0430\u044f \u043e\u0447\u0438\u0441\u0442\u043a\u0430 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0430 \u043f\u0440\u0438 \u0434\u043e\u0441\u0442\u0438\u0436\u0435\u043d\u0438\u0438 \u043a\u0432\u043e\u0442\u044b         purgeOnQuotaError: true       })     ]   }) )<\/code><\/pre>\n<p>  <\/p>\n<h2 id=\"obschie-rekomendacii\">\u041e\u0431\u0449\u0438\u0435 \u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0430\u0446\u0438\u0438<\/h2>\n<p>  <\/p>\n<p>\u041d\u0438\u0436\u0435 \u043f\u0440\u0438\u0432\u0435\u0434\u0435\u043d\u043e \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043f\u0440\u0438\u043c\u0435\u0440\u043e\u0432 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u0439 \u043a\u044d\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0434\u043b\u044f \u0440\u0430\u0437\u043d\u044b\u0445 \u0441\u043b\u0443\u0447\u0430\u0435\u0432.<\/p>\n<p>  <\/p>\n<h3 id=\"gugl-shrifty\">\u0413\u0443\u0433\u043b-\u0448\u0440\u0438\u0444\u0442\u044b<\/h3>\n<p>  <\/p>\n<p>\u0421\u0435\u0440\u0432\u0438\u0441 \u0433\u0443\u0433\u043b-\u0448\u0440\u0438\u0444\u0442\u043e\u0432 \u0441\u043e\u0441\u0442\u043e\u0438\u0442 \u0438\u0437 \u0434\u0432\u0443\u0445 \u0447\u0430\u0441\u0442\u0435\u0439:<\/p>\n<p>  <\/p>\n<ul>\n<li>\u0442\u0430\u0431\u043b\u0438\u0446\u0430 \u0441\u0442\u0438\u043b\u0435\u0439 \u0441 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u044f\u043c\u0438 <code>@font-face<\/code>, \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0449\u0438\u043c\u0438 \u0441\u0441\u044b\u043b\u043a\u0438 \u043d\u0430 \u0448\u0440\u0438\u0444\u0442\u044b<\/li>\n<li>\u0441\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0435 \u0444\u0430\u0439\u043b\u044b \u0441\u043e \u0448\u0440\u0438\u0444\u0442\u0430\u043c\u0438<\/li>\n<\/ul>\n<p>  <\/p>\n<p>\u0422\u0430\u0431\u043b\u0438\u0446\u0430 \u0441\u0442\u0438\u043b\u0435\u0439 \u043c\u043e\u0436\u0435\u0442 \u0447\u0430\u0441\u0442\u043e \u0438\u0437\u043c\u0435\u043d\u044f\u0442\u044c\u0441\u044f, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0434\u043b\u044f \u043d\u0435\u0435 \u043b\u0443\u0447\u0448\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u044e <code>stale-while-revalidate<\/code>, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435 \u043a\u044d\u0448\u0430 \u043f\u043e\u0441\u043b\u0435 \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0437\u0430\u043f\u0440\u043e\u0441\u0430. \u0414\u043b\u044f \u0444\u0430\u0439\u043b\u043e\u0432 \u0448\u0440\u0438\u0444\u0442\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u0435\u043d\u044f\u044e\u0442\u0441\u044f \u0440\u0435\u0434\u043a\u043e, \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u044e <code>cache-first<\/code>.<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">import { registerRoute } from 'workbox-routing' import { CacheFirst, StaleWhileRevalidate } from 'workbox-strategies' import { CacheableResponsePlugin } from 'workbox-cacheable-response' import { ExpirationPlugin } from 'workbox-expiration'  \/\/ \u041a\u044d\u0448\u0438\u0440\u0443\u0435\u043c \u0442\u0430\u0431\u043b\u0438\u0446\u0443 \u0441\u0442\u0438\u043b\u0435\u0439 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u0438 `stale-while-revalidate` registerRoute(   ({ url }) =&gt; url.origin === 'https:\/\/fonts.googleapis.com',   new StaleWhileRevalidate({     cacheName: 'google-fonts-stylesheets'   }) )  \/\/ \u041a\u044d\u0448\u0438\u0440\u0443\u0435\u043c \u0444\u0430\u0439\u043b\u044b \u0441\u043e \u0448\u0440\u0438\u0444\u0442\u0430\u043c\u0438 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u0438 `cache-first` \u043d\u0430 1 \u0433\u043e\u0434 registerRoute(   ({ url }) =&gt; url.origin === 'https:\/\/fonts.gstatic.com',   new CacheFirst({     cacheName: 'google-fonts-webfonts',     plugins: [       new CacheableResponsePlugin({         statuses: [0, 200],       }),       new ExpirationPlugin({         maxAgeSeconds: 60 * 60 * 24 * 365,         maxEntries: 30       })     ]   }) )<\/code><\/pre>\n<p>  <\/p>\n<h3 id=\"keshirovanie-izobrazheniy-1\">\u041a\u044d\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0439<\/h3>\n<p>  <\/p>\n<pre><code class=\"plaintext\">import { registerRoute } from 'workbox-routing' import { ExpirationPlugin } from 'workbox-expiration'  registerRoute(   ({ request }) =&gt; request.destination === 'image',   new CacheFirst({     cacheName: 'images',     plugins: [       new ExpirationPlugin({         maxEntries: 60,         maxAgeSeconds: 30 * 24 * 60 * 60 \/\/ 30 \u0434\u043d\u0435\u0439       })     ]   }) )<\/code><\/pre>\n<p>  <\/p>\n<h3 id=\"keshirovanie-js-i-css-faylov\">\u041a\u044d\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 <code>JS<\/code> \u0438 <code>CSS-\u0444\u0430\u0439\u043b\u043e\u0432<\/code><\/h3>\n<p>  <\/p>\n<pre><code class=\"plaintext\">import { registerRoute } from 'workbox-routing' import { StaleWhileRevalidate } from 'workbox-strategies'  registerRoute(   ({ request }) =&gt;     request.destination === 'script' || request.destination === 'style',   new StaleWhileRevalidate({     cacheName: 'static-resources'   }) )<\/code><\/pre>\n<p>  <\/p>\n<h3 id=\"keshirovanie-kontenta-iz-raznyh-istochnikov\">\u041a\u044d\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043a\u043e\u043d\u0442\u0435\u043d\u0442\u0430 \u0438\u0437 \u0440\u0430\u0437\u043d\u044b\u0445 \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u043e\u0432<\/h3>\n<p>  <\/p>\n<pre><code class=\"plaintext\">import { registerRoute } from 'workbox-routing' import { StaleWhileRevalidate } from 'workbox-strategies'  registerRoute(   ({ url }) =&gt;     url.origin === 'https:\/\/fonts.googleapis.com' ||     url.origin === 'https:\/\/fonts.gstatic.com',   new StaleWhileRevalidate() )<\/code><\/pre>\n<p>  <\/p>\n<h3 id=\"keshirovanie-resursov-iz-opredelennogo-istochnika\">\u041a\u044d\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432 \u0438\u0437 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u043e\u0433\u043e \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u0430<\/h3>\n<p>  <\/p>\n<pre><code class=\"plaintext\">import { registerRoute } from 'workbox-routing' import { CacheFirst } from 'workbox-strategies' import { CacheableResponsePlugin } from 'workbox-cacheable-response' import { ExpirationPlugin } from 'workbox-expiration'  registerRoute(   ({ url }) =&gt; url.origin === 'https:\/\/hacker-news.firebaseio.com',   new CacheFirst({     cacheName: 'stories',     plugins: [       new ExpirationPlugin({         maxEntries: 50,         maxAgeSeconds: 5 * 60 \/\/ 5 \u043c\u0438\u043d\u0443\u0442       }),       new CacheableResponsePlugin({         statuses: [0, 200]       })     ]   }) )<\/code><\/pre>\n<p>  <\/p>\n<h3 id=\"ustanovka-taymera-na-vypolnenie-setevogo-zaprosa\">\u0423\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430 \u0442\u0430\u0439\u043c\u0435\u0440\u0430 \u043d\u0430 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u0441\u0435\u0442\u0435\u0432\u043e\u0433\u043e \u0437\u0430\u043f\u0440\u043e\u0441\u0430<\/h3>\n<p>  <\/p>\n<p>\u0412 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u043c \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u043c\u044b \u043f\u044b\u0442\u0430\u0435\u043c\u0441\u044f \u0432\u0435\u0440\u043d\u0443\u0442\u044c \u043e\u0442\u0432\u0435\u0442 \u0438\u0437 \u0441\u0435\u0442\u0438. \u0415\u0441\u043b\u0438 \u0437\u0430\u043f\u0440\u043e\u0441 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f \u0434\u043e\u043b\u044c\u0448\u0435 3 \u0441\u0435\u043a\u0443\u043d\u0434, \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442\u0441\u044f \u043e\u0442\u0432\u0435\u0442 \u0438\u0437 \u043a\u044d\u0448\u0430:<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">import { registerRoute } from 'workbox-routing' import { NetworkFirst } from 'workbox-strategies' import { ExpirationPlugin } from 'workbox-expiration'  registerRoute(   ({ url }) =&gt; url.origin === 'https:\/\/hacker-news.firebaseio.com',   new NetworkFirst({     networkTimeoutSeconds: 3,     cacheName: 'stories',     plugins: [       new ExpirationPlugin({         maxEntries: 50,         maxAgeSeconds: 5 * 60 \/\/ 5 \u043c\u0438\u043d\u0443\u0442       })     ]   }) )<\/code><\/pre>\n<p>  <\/p>\n<h3 id=\"keshirovanie-resursov-iz-opredelennoy-poddirektorii\">\u041a\u044d\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432 \u0438\u0437 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u043e\u0439 \u043f\u043e\u0434\u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u0438<\/h3>\n<p>  <\/p>\n<pre><code class=\"plaintext\">import { registerRoute } from 'workbox-routing' import { StaleWhileRevalidate } from 'workbox-strategies'  registerRoute(   ({ url }) =&gt;     url.origin === self.location.origin &amp;&amp; url.pathname.startsWith('\/static\/'),   new StaleWhileRevalidate() )<\/code><\/pre>\n<p>  <\/p>\n<h3 id=\"keshirovanie-na-osnove-tipa-resursa\">\u041a\u044d\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u0442\u0438\u043f\u0430 \u0440\u0435\u0441\u0443\u0440\u0441\u0430<\/h3>\n<p>  <\/p>\n<pre><code class=\"plaintext\">import { registerRoute } from 'workbox-routing' import { CacheFirst } from 'workbox-strategies' import { ExpirationPlugin } from 'workbox-expiration'  registerRoute(   \/\/ \u041a\u0430\u0441\u0442\u043e\u043c\u043d\u0430\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f `matchCallback`   ({ request }) =&gt; request.destination === 'audio',   new CacheFirst({     cacheName: 'audio',     plugins: [       new ExpirationPlugin({         maxEntries: 60,         maxAgeSeconds: 30 * 24 * 60 * 60 \/\/ 30 \u0434\u043d\u0435\u0439       })     ]   }) )<\/code><\/pre>\n<p>  <\/p>\n<h2 id=\"dostup-k-keshu-iz-prilozheniya\">\u0414\u043e\u0441\u0442\u0443\u043f \u043a \u043a\u044d\u0448\u0443 \u0438\u0437 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f<\/h2>\n<p>  <\/p>\n<p><code>Cache Storage API<\/code> \u0434\u043e\u0441\u0442\u0443\u043f\u0435\u043d \u043a\u0430\u043a \u0432 \u0421\u0412, \u0442\u0430\u043a \u0438 \u0432 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0435 <code>window<\/code>. \u0415\u0441\u043b\u0438 \u0432\u044b \u0445\u043e\u0442\u0438\u0442\u0435 \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u044c \u043a\u044d\u0448 \u2014 \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0438\u043b\u0438 \u0443\u0434\u0430\u043b\u0438\u0442\u044c \u0438\u0437 \u043d\u0435\u0433\u043e \u0437\u0430\u043f\u0438\u0441\u0438 \u0438\u043b\u0438 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0441\u043f\u0438\u0441\u043e\u043a \u043a\u044d\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0445 <code>URL<\/code>, \u0432\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u044d\u0442\u043e \u043d\u0430\u043f\u0440\u044f\u043c\u0443\u044e, \u0431\u0435\u0437 \u043e\u0431\u0440\u0430\u0449\u0435\u043d\u0438\u044f \u043a \u0421\u0412 \u0447\u0435\u0440\u0435\u0437 <code>postMessage()<\/code>.<\/p>\n<p>  <\/p>\n<p>\u0412 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u043c \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u043c\u044b \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0432 \u043a\u044d\u0448 \u043d\u043e\u0432\u044b\u0435 \u0437\u0430\u043f\u0438\u0441\u0438 \u043f\u0440\u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u043c \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u043e\u0433\u043e \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u0432 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0438:<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">\/\/ \u0412 app.js async function addToCache(urls) {   const myCache = await window.caches.open('my-cache')   await myCache.addAll(urls) }  \/\/ \u0412\u044b\u0437\u044b\u0432\u0430\u0435\u043c `addToCache` \u0432 \u043b\u044e\u0431\u043e\u0435 \u0432\u0440\u0435\u043c\u044f, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043f\u043e\u0441\u043b\u0435 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b window.addEventListener('load', () =&gt; {   \/\/ \u041e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u043c \u0441\u043f\u0438\u0441\u043e\u043a \u043e\u0442\u043d\u043e\u0441\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0445 `URL` \u0434\u043b\u044f \u0442\u0435\u043a\u0443\u0449\u0435\u0439 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b   addToCache(['\/static\/relatedUrl1', '\/static\/relatedUrl2']) })<\/code><\/pre>\n<p>  <\/p>\n<p>\u041d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u043a\u044d\u0448\u0430 <code>my-cache<\/code> \u0437\u0430\u0442\u0435\u043c \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u043e \u0432 \u0421\u0412:<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">\/\/ Inside service-worker.js:  import { registerRoute } from 'workbox-routing' import { StaleWhileRevalidate } from 'workbox-strategies'  registerRoute(   ({ url }) =&gt;     url.origin === self.location.origin &amp;&amp; url.pathname.startsWith('\/static\/'),   new StaleWhileRevalidate({     cacheName: 'my-cache'   }) )<\/code><\/pre>\n<p>  <\/p>\n<h2 id=\"prodvinutye-tehniki\">\u041f\u0440\u043e\u0434\u0432\u0438\u043d\u0443\u0442\u044b\u0435 \u0442\u0435\u0445\u043d\u0438\u043a\u0438<\/h2>\n<p>  <\/p>\n<h3 id=\"predlagaem-polzovatelyu-perezagruzit-stranicu\">\u041f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u0435\u043c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044e \u043f\u0435\u0440\u0435\u0437\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044c \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443<\/h3>\n<p>  <\/p>\n<p>\u0425\u043e\u0440\u043e\u0448\u0435\u0439 \u043f\u0440\u0430\u043a\u0442\u0438\u043a\u043e\u0439 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u201c\u0431\u0430\u043d\u043d\u0435\u0440\u0430\u201d (\u043e\u043f\u043e\u0432\u0435\u0449\u0435\u043d\u0438\u044f) \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f \u0438 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438 \u0421\u0412.<\/p>\n<p>  <\/p>\n<p>\u0414\u043b\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u044d\u0442\u043e\u0433\u043e \u043f\u0430\u0442\u0442\u0435\u0440\u043d\u0430 \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043a\u043e\u0434 \u043d\u0430 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0435 \u0438 \u0432 \u0421\u0412.<\/p>\n<p>  <\/p>\n<p><strong>\u041a\u043e\u0434 \u043d\u0430 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0435<\/strong><\/p>\n<p>  <\/p>\n<pre><code class=\"html\">&lt;script type=&quot;module&quot;&gt;   import { Workbox } from 'https:\/\/storage.googleapis.com\/workbox-cdn\/releases\/6.1.5\/workbox-window.prod.mjs'    if ('serviceWorker' in navigator) {     const wb = new Workbox('\/sw.js')     let registration      const showSkipWaitingPrompt = (event) =&gt; {       \/\/ `event.wasWaitingBeforeRegister` \u0431\u0443\u0434\u0435\u0442 \u0438\u043c\u0435\u0442\u044c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 `false`, \u0435\u0441\u043b\u0438 \u044d\u0442\u043e       \/\/ \u043f\u0435\u0440\u0432\u044b\u0439 \u0440\u0430\u0437, \u043a\u043e\u0433\u0434\u0430 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u043d\u044b\u0439 \u0421\u0412 \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0432 \u0440\u0435\u0436\u0438\u043c\u0435 \u043e\u0436\u0438\u0434\u0430\u043d\u0438\u044f.       \/\/ \u041a\u043e\u0433\u0434\u0430 `event.wasWaitingBeforeRegister` \u0438\u043c\u0435\u0435\u0442 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 `true`, \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0438\u0439       \/\/ \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u043d\u044b\u0439 \u0421\u0412 \u0432\u0441\u0435 \u0435\u0449\u0435 \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0432 \u0440\u0435\u0436\u0438\u043c\u0435 \u043e\u0436\u0438\u0434\u0430\u043d\u0438\u044f.       \/\/ \u042d\u0442\u043e \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043a\u0430\u0441\u0442\u043e\u043c\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c UI.        \/\/ \u041f\u0440\u0435\u0434\u043f\u043e\u043b\u043e\u0436\u0438\u043c, \u0447\u0442\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0438\u043c\u0435\u0435\u0442 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 UI,       \/\/ \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043c\u043e\u0436\u0435\u0442 \u043f\u0440\u0438\u043d\u044f\u0442\u044c \u0438\u043b\u0438 \u043e\u0442\u043a\u043b\u043e\u043d\u0438\u0442\u044c       const prompt = createUIPrompt({         onAccept: () =&gt; {           \/\/ \u0414\u043e\u043f\u0443\u0441\u0442\u0438\u043c, \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043f\u0440\u0438\u043d\u044f\u043b \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435, \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u0443\u0435\u043c \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a,           \/\/ \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u0435\u0440\u0435\u0437\u0430\u0433\u0440\u0443\u0437\u0438\u0442 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443 \u043a\u0430\u043a \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0438\u0439 \u043e\u0436\u0438\u0434\u0430\u044e\u0449\u0438\u0439           \/\/ \u0421\u0412 \u043f\u043e\u043b\u0443\u0447\u0438\u0442 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u044c \u043d\u0430\u0434 \u043d\u0435\u0439           wb.addEventListener('controlling', (event) =&gt; {             window.location.reload()           })            wb.messageSkipWaiting()         },          onReject: () =&gt; {           prompt.dismiss()         }       })     }      \/\/ \u0420\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u0443\u0435\u043c \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442 \u043c\u043e\u043c\u0435\u043d\u0442, \u043a\u043e\u0433\u0434\u0430     \/\/ \u0421\u0412 \u0431\u044b\u043b \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d, \u043d\u043e \u043e\u0436\u0438\u0434\u0430\u0435\u0442 \u0430\u043a\u0442\u0438\u0432\u0430\u0446\u0438\u0438     wb.addEventListener('waiting', showSkipWaitingPrompt)      wb.register()   } &lt;\/script&gt;<\/code><\/pre>\n<p>  <\/p>\n<p>\u041f\u0440\u0438 \u043e\u0431\u043d\u0430\u0440\u0443\u0436\u0435\u043d\u0438\u0438 \u043e\u0436\u0438\u0434\u0430\u044e\u0449\u0435\u0433\u043e \u0421\u0412, \u043c\u044b \u0441\u043e\u043e\u0431\u0449\u0430\u0435\u043c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044e \u043e \u0442\u043e\u043c, \u0447\u0442\u043e \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u0430 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u043d\u0430\u044f \u0432\u0435\u0440\u0441\u0438\u044f \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0438 \u0437\u0430\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0435\u043c \u0443 \u043d\u0435\u0433\u043e \u0440\u0430\u0437\u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u043d\u0430 \u043f\u0435\u0440\u0435\u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0443 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b. \u0415\u0441\u043b\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u0438\u043b \u0440\u0430\u0437\u0440\u0435\u0448\u0435\u043d\u0438\u0435, \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c <code>messageSkipWaiting()<\/code> \u0434\u043b\u044f \u0443\u043a\u0430\u0437\u0430\u043d\u0438\u044f \u043e\u0436\u0438\u0434\u0430\u044e\u0449\u0435\u043c\u0443 \u0421\u0412 \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c <code>self.skipWaiting()<\/code>, \u0447\u0442\u043e \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442 \u043d\u0430\u0447\u0430\u043b\u043e \u0435\u0433\u043e \u0430\u043a\u0442\u0438\u0432\u0430\u0446\u0438\u0438. \u041f\u043e\u0441\u043b\u0435 \u0442\u043e\u0433\u043e, \u043a\u0430\u043a \u043d\u043e\u0432\u044b\u0439 \u0421\u0412 \u0431\u044b\u043b \u0430\u043a\u0442\u0438\u0432\u0438\u0440\u043e\u0432\u0430\u043d \u0438 \u043f\u043e\u043b\u0443\u0447\u0438\u043b \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u044c \u043d\u0430\u0434 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0435\u0439, \u043c\u044b \u043f\u0435\u0440\u0435\u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0435\u043c \u0435\u0435, \u0447\u0442\u043e \u043f\u0440\u0438\u0432\u043e\u0434\u0438\u0442 \u043a \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044e \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0439 \u0432\u0435\u0440\u0441\u0438\u0438 \u043f\u0440\u0435\u0434\u0432\u0430\u0440\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043a\u044d\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0445 \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432.<\/p>\n<p>  <\/p>\n<p><strong>\u041a\u043e\u0434 \u0432 \u0421\u0412<\/strong><\/p>\n<p>  <\/p>\n<p>\u0415\u0441\u043b\u0438 \u0432\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0435 \u043e\u0434\u0438\u043d \u0438\u0437 \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u044b\u0445 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u043e\u0432 <code>WB<\/code> \u0432 \u0440\u0435\u0436\u0438\u043c\u0435 <code>GenerateSW<\/code> \u0438 <code>skipWaiting<\/code> \u0438\u043c\u0435\u0435\u0442 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 <code>false<\/code> (\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e), \u0442\u043e \u043f\u0440\u0438\u0432\u0435\u0434\u0435\u043d\u043d\u044b\u0439 \u043d\u0438\u0436\u0435 \u043a\u043e\u0434 \u0431\u0443\u0434\u0435\u0442 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0432\u043a\u043b\u044e\u0447\u0435\u043d \u0432 \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u043c\u043e\u0433\u043e \u0421\u0412.<\/p>\n<p>  <\/p>\n<p>\u0415\u0441\u043b\u0438 \u0432\u044b \u0441\u043e\u0437\u0434\u0430\u0435\u0442\u0435 \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0433\u043e \u0421\u0412 \u0438\u043b\u0438 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442\u0435 \u0432 \u0440\u0435\u0436\u0438\u043c\u0435 <code>InjectManifest<\/code>, \u0442\u043e\u0433\u0434\u0430 \u0432 \u043a\u043e\u0434 \u0421\u0412 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0435:<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">addEventListener('message', (event) =&gt; {   if (event.data &amp;&amp; event.data.type === 'SKIP_WAITING') {     self.skipWaiting()   } })<\/code><\/pre>\n<p>  <\/p>\n<p>\u042d\u0442\u043e\u0442 \u043a\u043e\u0434 &quot;\u0441\u043b\u0443\u0448\u0430\u0435\u0442&quot; \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u0441 <code>type: 'SKIP_WAITING'<\/code> \u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u0442 \u043c\u0435\u0442\u043e\u0434 <code>self.skipWaiting()<\/code> \u0434\u043b\u044f \u0430\u043a\u0442\u0438\u0432\u0430\u0446\u0438\u0438 \u0421\u0412.<\/p>\n<p>  <\/p>\n<h3 id=\"podgotovka-kesha-vo-vremya-vypolneniya\">\u041f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u043a\u0430 \u043a\u044d\u0448\u0430 \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f<\/h3>\n<p>  <\/p>\n<p>\u041f\u043e\u0441\u043b\u0435 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u043e\u0432 \u0434\u043b\u044f \u043a\u044d\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432, \u043c\u043e\u0436\u0435\u0442 \u0432\u043e\u0437\u043d\u0438\u043a\u043d\u0443\u0442\u044c \u0436\u0435\u043b\u0430\u043d\u0438\u0435 \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0444\u0430\u0439\u043b\u044b \u0432 \u043a\u044d\u0448 \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438 \u0421\u0412.<\/p>\n<p>  <\/p>\n<p>\u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043d\u0443\u0436\u043d\u044b\u0435 \u0440\u0435\u0441\u0443\u0440\u0441\u044b \u0441\u043b\u0435\u0434\u0443\u0435\u0442 \u0437\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0432 \u043a\u044d\u0448 \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f:<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">import { cacheNames } from 'workbox-core'  self.addEventListener('install', (event) =&gt; {   const urls = [     \/* ... *\/   ]   const cacheName = cacheNames.runtime   event.waitUntil(     caches       .open(cacheName)       .then((cache) =&gt; cache.addAll(urls))     ) })<\/code><\/pre>\n<p>  <\/p>\n<p>\u041f\u0440\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0438 \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u0439 \u0441 \u043a\u0430\u0441\u0442\u043e\u043c\u043d\u044b\u043c \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435\u043c \u0434\u043b\u044f \u043a\u044d\u0448\u0430 \u043f\u0440\u043e\u0441\u0442\u043e \u043f\u0440\u0438\u0441\u0432\u043e\u0439\u0442\u0435 \u044d\u0442\u043e \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0443 <code>cacheName<\/code>.<\/p>\n<p>  <\/p>\n<h3 id=\"rezervnyy-kontent-1\">\u0420\u0435\u0437\u0435\u0440\u0432\u043d\u044b\u0439 \u043a\u043e\u043d\u0442\u0435\u043d\u0442<\/h3>\n<p>  <\/p>\n<p>\u0412\u043e\u0437\u0432\u0440\u0430\u0442 \u0440\u0435\u0437\u0435\u0440\u0432\u043d\u043e\u0433\u043e \u043e\u0442\u0432\u0435\u0442\u0430 \u2014 \u044d\u0442\u043e \u043b\u0443\u0447\u0448\u0435, \u0447\u0435\u043c \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0438\u0435 \u043e\u0442\u0432\u0435\u0442\u0430. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043c\u043e\u0436\u043d\u043e \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0442\u044c \u0437\u0430\u043c\u0435\u043d\u0438\u0442\u0435\u043b\u044c (placeholder) \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f, \u043a\u043e\u0433\u0434\u0430 \u043d\u0435 \u0443\u0434\u0430\u043b\u043e\u0441\u044c \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0441\u0430\u043c\u043e \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435, \u0438\u043b\u0438 \u0440\u0435\u0437\u0435\u0440\u0432\u043d\u0443\u044e <code>HTML-\u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443<\/code> \u0432\u043c\u0435\u0441\u0442\u043e \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u043e\u0439 \u043e\u0444\u043b\u0430\u0439\u043d-\u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b, \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u043c\u043e\u0439 \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u043e\u043c.<\/p>\n<p>  <\/p>\n<p><strong>\u0420\u0435\u0437\u0435\u0440\u0432\u043d\u0430\u044f \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430<\/strong><\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">import * as navigationPreload from 'workbox-navigation-preload' import { registerRoute, NavigationRoute } from 'workbox-routing' import { NetworkOnly } from 'workbox-strategies'  const CACHE_NAME = 'offline-html' \/\/ \u041c\u044b \u0438\u0441\u0445\u043e\u0434\u0438\u043c \u0438\u0437 \u043f\u0440\u0435\u0434\u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u044f, \u0447\u0442\u043e `\/offline.html` - \u044d\u0442\u043e `URL` \u0441\u0430\u043c\u043e\u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e\u0439 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b \/\/ (\u0431\u0435\u0437 \u0432\u043d\u0435\u0448\u043d\u0438\u0445 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0439 \u0438\u043b\u0438 \u0441\u0442\u0438\u043b\u0435\u0439) const FALLBACK_HTML_URL = '\/offline.html' \/\/ \u0417\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u043c \u0440\u0435\u0437\u0435\u0440\u0432\u043d\u0443\u044e \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443 \u0432 \u043a\u044d\u0448 \u043f\u0440\u0438 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0435 \u0421\u0412 self.addEventListener('install', async (event) =&gt; {   event.waitUntil(     caches.open(CACHE_NAME).then((cache) =&gt; cache.add(FALLBACK_HTML_URL))   ) })  navigationPreload.enable()  const networkOnly = new NetworkOnly() const navigationHandler = async (params) =&gt; {   try {     \/\/ \u041f\u044b\u0442\u0430\u0435\u043c\u0441\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u0441\u0435\u0442\u0435\u0432\u043e\u0439 \u0437\u0430\u043f\u0440\u043e\u0441     return await networkOnly.handle(params)   } catch (error) {     \/\/ \u0412 \u0441\u043b\u0443\u0447\u0430\u0435 \u043f\u0440\u043e\u0432\u0430\u043b\u0430 \u0437\u0430\u043f\u0440\u043e\u0441\u0430, \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c \u0440\u0435\u0437\u0435\u0440\u0432\u043d\u0443\u044e c\u0442\u0440\u0430\u043d\u0438\u0446\u0443 \u0438\u0437 \u043a\u044d\u0448\u0430     return caches.match(FALLBACK_HTML_URL, {       cacheName: CACHE_NAME     })   } }  \/\/ \u0420\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u0443\u0435\u043c \u0434\u0430\u043d\u043d\u0443\u044e \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u044e \u0434\u043b\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0432\u0441\u0435\u0445 \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u043e\u0432 registerRoute(new NavigationRoute(navigationHandler))<\/code><\/pre>\n<p>  <\/p>\n<p><strong>\u0411\u043e\u043b\u0435\u0435 \u0441\u043b\u043e\u0436\u043d\u044b\u0439 \u043f\u0440\u0438\u043c\u0435\u0440<\/strong><\/p>\n<p>  <\/p>\n<p>\u0412\u0441\u0435 \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u044b\u0435 \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u0438 \u043e\u0442\u043a\u043b\u043e\u043d\u044f\u044e\u0442\u0441\u044f (reject) \u043e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u043e \u043f\u0440\u0438 \u043f\u0440\u043e\u0432\u0430\u043b\u0435 \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u0438\/\u0438\u043b\u0438 \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0438\u0438 \u043a\u044d\u0448\u0430. \u042d\u0442\u043e \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u044b\u0439 &quot;\u043f\u0435\u0440\u0435\u0445\u0432\u0430\u0442\u0447\u0438\u043a&quot; \u0434\u043b\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0432\u0441\u0435\u0445 \u043e\u0448\u0438\u0431\u043e\u043a.<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">import { matchPrecache, precacheAndRoute } from 'workbox-precaching' import { registerRoute, setDefaultHandler, setCatchHandler } from 'workbox-routing' import { CacheFirst, StaleWhileRevalidate } from 'workbox-strategies'  \/\/ \u041e\u043f\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e: \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0440\u0435\u0436\u0438\u043c `injectManifest` \u0441 \u043e\u0434\u043d\u0438\u043c \u0438\u0437 \/\/ \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u044b\u0445 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u043e\u0432 \u0434\u043b\u044f \u043f\u0440\u0435\u0434\u0432\u0430\u0440\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0433\u043e \u043a\u044d\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0441\u043f\u0438\u0441\u043a\u0430 `URL`, \u0432\u043a\u043b\u044e\u0447\u0430\u044f \u0440\u0435\u0437\u0435\u0440\u0432\u043d\u044b\u0435 precacheAndRoute(self.__WB_MANIFEST)  \/\/ \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u044e &quot;\u0441\u043d\u0430\u0447\u0430\u043b\u0430 \u043a\u044d\u0448&quot; \u0438 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u044b\u0439 \u043a\u044d\u0448 \u0434\u043b\u044f \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0439 registerRoute(   ({ request }) =&gt; request.destination === 'image',   new CacheFirst({     cacheName: 'images',     plugins: [...]   }) )  \/\/ \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u044e &quot;\u0441\u0447\u0438\u0442\u0430\u0435\u0442\u0441\u044f \u0443\u0441\u0442\u0430\u0440\u0435\u0432\u0448\u0438\u043c \u043f\u043e\u0441\u043b\u0435 \u0437\u0430\u043f\u0440\u043e\u0441\u0430&quot; \u0434\u043b\u044f \u0434\u0440\u0443\u0433\u0438\u0445 \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432 setDefaultHandler(new StaleWhileRevalidate())  \/\/ \u0414\u0430\u043d\u043d\u044b\u0439 &quot;\u043f\u0435\u0440\u0435\u0445\u0432\u0430\u0442\u0447\u0438\u043a&quot; \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u0442\u0441\u044f \u043f\u0440\u0438 \u043f\u0440\u043e\u0432\u0430\u043b\u0435 \u043b\u044e\u0431\u043e\u0433\u043e \u0437\u0430\u043f\u0440\u043e\u0441\u0430 setCatchHandler(async ({ event }) =&gt; {   \/\/ `FALLBACK_URL` \u0434\u043e\u043b\u0436\u0435\u043d \u0431\u044b\u0442\u044c \u0437\u0430\u043f\u0438\u0441\u0430\u043d \u0432 \u043a\u044d\u0448 \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0438\u043b\u0438 \u043f\u0440\u0435\u0434\u0432\u0430\u0440\u0438\u0442\u0435\u043b\u044c\u043d\u043e   \/\/ \u0415\u0441\u043b\u0438 \u043e\u043d \u0431\u044b\u043b \u043f\u0440\u0435\u0434\u0432\u0430\u0440\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043a\u044d\u0448\u0438\u0440\u043e\u0432\u0430\u043d, \u0441\u043b\u0435\u0434\u0443\u0435\u0442 \u0432\u044b\u0437\u044b\u0432\u0430\u0442\u044c   \/\/ `matchPrecache(FALLBACK_URL)` (\u0438\u0437 \u043f\u0430\u043a\u0435\u0442\u0430 `workbox-precaching`)   \/\/ \u0434\u043b\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u043e\u0442\u0432\u0435\u0442\u0430 \u0438\u0437 \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e\u0433\u043e \u043a\u044d\u0448\u0430   \/\/   \/\/ \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0439\u0442\u0435 `event`, `request` \u0438 `url` \u0434\u043b\u044f \u0444\u043e\u0440\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e\u0433\u043e \u043e\u0442\u0432\u0435\u0442\u0430.   \/\/ \u041e\u0434\u043d\u0438\u043c \u0438\u0437 \u0441\u043f\u043e\u0441\u043e\u0431\u043e\u0432 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 `request.destination`   switch (event.request.destination) {     case 'document':       \/\/ \u041f\u0440\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0438 \u043f\u0440\u0435\u0434\u0432\u0430\u0440\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043a\u044d\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0445 `URL`,       \/\/ \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c matchPrecache(FALLBACK_HTML_URL)       return caches.match(FALLBACK_HTML_URL)     break      case 'image':       return caches.match(FALLBACK_IMAGE_URL)     break      case 'font':       return caches.match(FALLBACK_FONT_URL)     break      default:       \/\/ \u041f\u0440\u0438 \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0438\u0438 \u0440\u0435\u0437\u0435\u0440\u0432\u043d\u043e\u0433\u043e \u043a\u043e\u043d\u0442\u0435\u043d\u0442\u0430, \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c \u043e\u0448\u0438\u0431\u043a\u0443       return Response.error()   } })<\/code><\/pre>\n<p>  <\/p>\n<h3 id=\"vypolnenie-avtonomnyh-zaprosov\">\u0412\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u0430\u0432\u0442\u043e\u043d\u043e\u043c\u043d\u044b\u0445 \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432<\/h3>\n<p>  <\/p>\n<p>\u0411\u043e\u043b\u044c\u0448\u0438\u043d\u0441\u0442\u0432\u043e \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u043e\u0432 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 \u043e\u0434\u043d\u0443 \u0438\u0437 \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u0439 \u043a\u0430\u043a \u0447\u0430\u0441\u0442\u044c \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0438\u0437\u0430\u0442\u043e\u0440\u0430. \u0414\u0430\u043d\u043d\u0430\u044f \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0440\u0435\u0430\u0433\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043d\u0430 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u043e\u0435 \u0441\u043e\u0431\u044b\u0442\u0438\u0435 <code>fetch<\/code> \u043e\u0442\u0432\u0435\u0442\u043e\u043c, \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u043c \u043e\u0442 \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u0438.<\/p>\n<p>  <\/p>\n<p>\u0421\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0442 \u0441\u0438\u0442\u0443\u0430\u0446\u0438\u0438, \u043a\u043e\u0433\u0434\u0430 \u043c\u044b \u0445\u043e\u0442\u0438\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u044e \u0432 \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0439 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0435 \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0438\u0437\u0430\u0442\u043e\u0440\u0430 \u0438\u043b\u0438 \u0432\u043c\u0435\u0441\u0442\u043e \u043e\u0431\u044b\u0447\u043d\u043e\u0433\u043e \u0437\u0430\u043f\u0440\u043e\u0441\u0430 <code>fetch()<\/code>.<\/p>\n<p>  <\/p>\n<p>\u0412 \u0442\u0430\u043a\u0438\u0445 \u0441\u043b\u0443\u0447\u0430\u044f\u0445 \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u044e \u0432 &quot;\u0430\u0432\u0442\u043e\u043d\u043e\u043c\u043d\u043e\u043c&quot; \u0440\u0435\u0436\u0438\u043c\u0435:<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">import { NetworkFirst } from 'workbox-strategies'  \/\/ \u0412 \u0421\u0412 const strategy = new NetworkFirst({ networkTimeoutSeconds: 10 })  const response = await strategy.handle({   request: new Request('https:\/\/example.com\/path\/to\/file') }) \/\/ \u041e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u043c \u043e\u0442\u0432\u0435\u0442<\/code><\/pre>\n<p>  <\/p>\n<p>\u041f\u0430\u0440\u0430\u043c\u0435\u0442\u0440 <code>request<\/code> \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u043c \u0438 \u0434\u043e\u043b\u0436\u0435\u043d \u0438\u043c\u0435\u0442\u044c \u0442\u0438\u043f <code>Request<\/code>.<\/p>\n<p>  <\/p>\n<p>\u041f\u0430\u0440\u0430\u043c\u0435\u0442\u0440 <code>event<\/code> \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043e\u043f\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u044b\u043c <code>ExtendableEvent<\/code>. \u0415\u0441\u043b\u0438 \u0434\u0430\u043d\u043d\u044b\u0439 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440 \u0443\u043a\u0430\u0437\u0430\u043d, \u043e\u043d \u0431\u0443\u0434\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0434\u043b\u044f \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0421\u0412 (\u0447\u0435\u0440\u0435\u0437 <code>event.waitUntil()<\/code>) \u0432 \u0442\u0435\u0447\u0435\u043d\u0438\u0435 \u0432\u0440\u0435\u043c\u0435\u043d\u0438, \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e\u0433\u043e \u0434\u043b\u044f \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u044f &quot;\u0444\u043e\u043d\u043e\u0432\u043e\u0433\u043e&quot; \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f \u043a\u044d\u0448\u0430 \u0438 \u0435\u0433\u043e \u043e\u0447\u0438\u0441\u0442\u043a\u0438.<\/p>\n<p>  <\/p>\n<p><code>handle()<\/code> \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u043f\u0440\u043e\u043c\u0438\u0441 \u0434\u043b\u044f \u043e\u0431\u044a\u0435\u043a\u0442\u0430 <code>Response<\/code>.<\/p>\n<p>  <\/p>\n<p><strong>\u0411\u043e\u043b\u0435\u0435 \u0441\u043b\u043e\u0436\u043d\u044b\u0439 \u043f\u0440\u0438\u043c\u0435\u0440<\/strong><\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">import { StaleWhileRevalidate } from 'workbox-strategies'  self.addEventListener('fetch', (event) =&gt; {   if (event.request.url.endsWith('\/complexRequest')) {     event.respondWith(       (async () =&gt; {         \/\/ \u041f\u0440\u043e\u0434\u0432\u0438\u043d\u0443\u0442\u0430\u044f \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u0438         const strategy = new StaleWhileRevalidate({ cacheName: 'api-cache' })          \/\/ \u0412\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u043c \u0434\u0432\u0430 \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u0438.         \/\/ \u041f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u043c\u044b \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u043c `event`, `event.waitUntil()` \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438         const firstPromise = strategy.handle({           event,           request: 'https:\/\/example.com\/api1',         })         const secondPromise = strategy.handle({           event,           request: 'https:\/\/example.com\/api2',         })          const [firstResponse, secondResponse] = await Promise.all(           firstPromise,           secondPromise         )         const [firstBody, secondBody] = await Promise.all(           firstResponse.text(),           secondResponse.text()         )          \/\/ \u041f\u0440\u0435\u0434\u043f\u043e\u043b\u043e\u0436\u0438\u043c, \u0447\u0442\u043e \u043c\u044b \u043f\u0440\u043e\u0441\u0442\u043e \u0445\u043e\u0442\u0438\u043c \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u0438\u0442\u044c \u043f\u0435\u0440\u0432\u044b\u0439 \u043e\u0442\u0432\u0435\u0442 \u043e\u0442 API \u0441\u043e \u0432\u0442\u043e\u0440\u044b\u043c \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f         \/\/ \u0444\u0438\u043d\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u043e\u0442\u0432\u0435\u0442\u0430 \u0432 \u0444\u043e\u0440\u043c\u0430\u0442\u0435 HTML         const compositeResponse = new Response(firstBody + secondBody, {           headers: { 'content-type': 'text\/html' },         })          return compositeResponse       })()     )   } })<\/code><\/pre>\n<p>  <\/p>\n<h3 id=\"keshirovanie-audio-i-video\">\u041a\u044d\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0430\u0443\u0434\u0438\u043e \u0438 \u0432\u0438\u0434\u0435\u043e<\/h3>\n<p>  <\/p>\n<pre><code class=\"html\">&lt;!-- \u041d\u0430 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0435 --&gt; &lt;!-- \u0412 \u043d\u0430\u0441\u0442\u043e\u044f\u0449\u0435\u0435 \u0432\u0440\u0435\u043c\u044f \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430 \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u0430 `crossorigin` \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0439 \u0434\u0430\u0436\u0435 \u0434\u043b\u044f \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 \u0438\u0437 \u043e\u0434\u043d\u043e\u0433\u043e \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u0430 --&gt; &lt;video src=&quot;movie.mp4&quot; crossorigin=&quot;anonymous&quot;&gt;&lt;\/video&gt;<\/code><\/pre>\n<p>  <\/p>\n<pre><code class=\"plaintext\">import { registerRoute } from 'workbox-routing' import { CacheFirst } from 'workbox-strategies' import { CacheableResponsePlugin } from 'workbox-cacheable-response' import { RangeRequestsPlugin } from 'workbox-range-requests'  \/\/ \u0412 \u0421\u0412 \/\/ \u0414\u043b\u044f \u0437\u0430\u043f\u0438\u0441\u0438 \u043c\u0435\u0434\u0438\u0430 \u0432 \u043a\u044d\u0448 \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043a\u0430\u043a \u043f\u0440\u0435\u0434\u0432\u0430\u0440\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0435 \u043a\u044d\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435, \u0442\u0430\u043a \u0438 \u043f\u0440\u044f\u043c\u043e\u0439 \u0432\u044b\u0437\u043e\u0432 `cache.add()` \/\/ \/\/ \u0414\u0430\u043d\u043d\u044b\u0439 \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0438\u0437\u0430\u0442\u043e\u0440 \u043e\u0442\u043f\u0440\u0430\u0432\u0438\u0442 \u0441\u0435\u0442\u0435\u0432\u043e\u0439 \u0437\u0430\u043f\u0440\u043e\u0441 \u043f\u0440\u0438 \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0438\u0438 \u0441\u043e\u0432\u043f\u0430\u0434\u0435\u043d\u0438\u044f \u0441 \u043a\u044d\u0448\u0435\u043c, \/\/ \u043d\u043e \u043e\u043d \u043d\u0435 \u0431\u0443\u0434\u0435\u0442 \u0437\u0430\u043f\u043e\u043b\u043d\u044f\u0442\u044c \u043a\u044d\u0448 \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f. \/\/ \u0415\u0441\u043b\u0438 \u0438\u043c\u0435\u0435\u0442\u0441\u044f \u0441\u043e\u0432\u043f\u0430\u0434\u0435\u043d\u0438\u0435 \u0441 \u043a\u044d\u0448\u0435\u043c, \u043e\u043d, \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e, \u0431\u0443\u0434\u0435\u0442 \u0438\u043c\u0435\u0442\u044c \u0434\u0435\u043b\u043e \u0441 \u0447\u0430\u0441\u0442\u0438\u0447\u043d\u044b\u043c\u0438 \u043e\u0442\u0432\u0435\u0442\u0430\u043c\u0438 registerRoute(   ({ url }) =&gt; url.pathname.endsWith('.mp4'),   new CacheFirst({     cacheName: 'your-cache-name-here',     plugins: [       new CacheableResponsePlugin({ statuses: [200] }),       new RangeRequestsPlugin()     ]   }) )<\/code><\/pre>\n<p>  <\/p>\n<h2 id=\"avtomaticheskoe-sozdanie-sv\">\u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0435 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0421\u0412<\/h2>\n<p>  <\/p>\n<h3 id=\"workbox-cli\"><code>workbox-cli<\/code><\/h3>\n<p>  <\/p>\n<p>\u0423\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c <code>CLI<\/code>:<\/p>\n<p>  <\/p>\n<pre><code class=\"bash\">yarn global add workbox-cli # \u0438\u043b\u0438 npm i -g workbox-cli<\/code><\/pre>\n<p>  <\/p>\n<p>\u0417\u0430\u043f\u0443\u0441\u043a\u0430\u043c <code>wizard<\/code>. \u041e\u043d \u043d\u0430\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0435\u0442 <code>CLI<\/code> \u0434\u043b\u044f \u043f\u0440\u043e\u0435\u043a\u0442\u0430, \u0437\u0430\u0434\u0430\u0432\u0430\u044f \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0432\u043e\u043f\u0440\u043e\u0441\u043e\u0432 \u043e \u0435\u0433\u043e \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0435 \u0434\u043b\u044f \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u044f \u0444\u0430\u0439\u043b\u043e\u0432 \u0434\u043b\u044f \u043a\u044d\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f.<\/p>\n<p>  <\/p>\n<pre><code class=\"bash\">workbox wizard<\/code><\/pre>\n<p>  <\/p>\n<p>\u0421\u043e\u0437\u0434\u0430\u0435\u043c \u0421\u0412:<\/p>\n<p>  <\/p>\n<pre><code class=\"bash\">workbox generateSW workbox-config.js<\/code><\/pre>\n<p>  <\/p>\n<p>\u0420\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u0443\u0435\u043c \u0421\u0412 \u043d\u0430 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0435:<\/p>\n<p>  <\/p>\n<pre><code class=\"html\">&lt;script&gt;   \/\/ \u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0443 \u0421\u0412   if ('serviceWorker' in navigator) {     \/\/ \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0441\u043e\u0431\u044b\u0442\u0438\u0435 `load` \u043e\u0431\u044a\u0435\u043a\u0442\u0430 `window` \u0434\u043b\u044f \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u044f \u043c\u043e\u043c\u0435\u043d\u0442\u0430 \u043f\u043e\u043b\u043d\u043e\u0439 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b     window.addEventListener('load', () =&gt; {       navigator.serviceWorker.register('\/service-worker.js')     })   } &lt;\/script&gt;<\/code><\/pre>\n<p>  <\/p>\n<p>\u0414\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0432 <code>workbox-config.js<\/code> \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0443 <code>runtimeCaching<\/code> \u0434\u043b\u044f \u043a\u044d\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0439 \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f:<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">module.exports = {   globDirectory: 'build\/',   globPatterns: ['**\/*.{html,json,js,css}'],   swDest: 'build\/sw.js',    \/\/ \u041e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u043c \u043f\u0440\u0430\u0432\u0438\u043b\u0430 \u0434\u043b\u044f \u043a\u044d\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f   runtimeCaching: [     {       \/\/ \u041e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u043c \u0437\u0430\u043f\u0440\u043e\u0441 \u043d\u0430 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 \u0444\u0430\u0439\u043b\u043e\u0432 \u0441 \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u044f\u043c\u0438 .png, .jpg, .jpeg \u0438\u043b\u0438 .svg       urlPattern: \/\\.(?:png|jpg|jpeg|svg)$\/,        \/\/ \u041f\u0440\u0438\u043c\u0435\u043d\u044f\u0435\u043c \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u044e &quot;\u0441\u043d\u0430\u0447\u0430\u043b\u0430 \u043a\u044d\u0448&quot;       handler: 'CacheFirst',        options: {         \/\/ \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u043a\u0430\u0441\u0442\u043e\u043c\u043d\u043e\u0435 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u0434\u043b\u044f \u043a\u044d\u0448\u0430         cacheName: 'images',          \/\/ \u041a\u044d\u0448\u0438\u0440\u0443\u0435\u043c \u043d\u0435 \u0431\u043e\u043b\u0435\u0435 10 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0439         expiration: {           maxEntries: 10         }       }     }   ] }<\/code><\/pre>\n<p>  <\/p>\n<p>\u041f\u043e\u0434 \u043a\u0430\u043f\u043e\u0442\u043e\u043c <code>workbox-cli<\/code> \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 \u043c\u043e\u0434\u0443\u043b\u044c <code>workbox-build<\/code>, \u043e\u0431\u043b\u0435\u0433\u0447\u0430\u044f \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u044e <code>WB<\/code> \u0432 \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u0441\u0431\u043e\u0440\u043a\u0438 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043a\u043e\u043c\u0430\u043d\u0434\u043d\u043e\u0439 \u0441\u0442\u0440\u043e\u043a\u0438.<\/p>\n<p>  <\/p>\n<p><strong>\u0420\u0435\u0436\u0438\u043c\u044b <code>CLI<\/code><\/strong><\/p>\n<p>  <\/p>\n<p><code>CLI<\/code> \u0438\u043c\u0435\u0435\u0442 4 \u0440\u0435\u0436\u0438\u043c\u0430:<\/p>\n<p>  <\/p>\n<ul>\n<li><code>wizard<\/code>: \u043f\u043e\u0448\u0430\u0433\u043e\u0432\u043e\u0435 \u0440\u0443\u043a\u043e\u0432\u043e\u0434\u0441\u0442\u0432\u043e \u043f\u043e \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0435 <code>WB<\/code> \u0434\u043b\u044f \u043f\u0440\u043e\u0435\u043a\u0442\u0430<\/li>\n<li><code>generateSW<\/code>: \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044f \u0433\u043e\u0442\u043e\u0432\u043e\u0433\u043e \u0421\u0412<\/li>\n<li><code>injectManifest<\/code>: \u0432\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u043d\u0438\u0435 \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432 \u0434\u043b\u044f \u043f\u0440\u0435\u0434\u0432\u0430\u0440\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0433\u043e \u043a\u044d\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f<\/li>\n<li><code>copyLibraries<\/code>: \u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a <code>WB<\/code> \u0432 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044e \u043f\u0440\u043e\u0435\u043a\u0442\u0430<\/li>\n<\/ul>\n<p>  <\/p>\n<p><strong><code>wizard<\/code><\/strong><\/p>\n<p>  <\/p>\n<p><code>wizard<\/code> \u0437\u0430\u0434\u0430\u0435\u0442 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0432\u043e\u043f\u0440\u043e\u0441\u043e\u0432, \u0441\u0432\u044f\u0437\u0430\u043d\u043d\u044b\u0445 \u0441 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u043e\u0439 \u043f\u0440\u043e\u0435\u043a\u0442\u0430, \u0430 \u0442\u0430\u043a\u0436\u0435 \u0441 \u0442\u0435\u043c, \u043a\u0430\u043a\u0438\u0435 \u0444\u0430\u0439\u043b\u044b \u043d\u0443\u0436\u0434\u0430\u044e\u0442\u0441\u044f \u0432 \u043f\u0440\u0435\u0434\u0432\u0430\u0440\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u043c \u043a\u044d\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0438. \u041e\u0442\u0432\u0435\u0442\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442\u0441\u044f \u0434\u043b\u044f \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u0444\u0430\u0439\u043b\u0430 \u0441 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430\u043c\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u043f\u0440\u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0435 \u0432 \u0440\u0435\u0436\u0438\u043c\u0435 <code>generateSW<\/code>.<\/p>\n<p>  <\/p>\n<p>\u041d\u0430\u0447\u0430\u043b\u044c\u043d\u044b\u0439 \u0444\u0430\u0439\u043b \u0441 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430\u043c\u0438 \u043c\u043e\u0436\u043d\u043e \u043a\u0430\u0441\u0442\u043e\u043c\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043b\u044e\u0431\u044b\u0445 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u043c\u044b\u0445 \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043a.<\/p>\n<p>  <\/p>\n<p><strong><code>generateSW<\/code><\/strong><\/p>\n<p>  <\/p>\n<p>\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0434\u043b\u044f \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u0433\u043e\u0442\u043e\u0432\u043e\u0433\u043e \u0421\u0412 \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u0444\u0430\u0439\u043b\u0430 \u0441 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430\u043c\u0438.<\/p>\n<p>  <\/p>\n<pre><code class=\"bash\">workbox generateSW path\/to\/config.js<\/code><\/pre>\n<p>  <\/p>\n<p>\u041a\u043e\u0433\u0434\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c:<\/p>\n<p>  <\/p>\n<ul>\n<li>\u0432\u044b \u0445\u043e\u0442\u0438\u0442\u0435 \u043f\u0440\u0435\u0434\u0432\u0430\u0440\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043a\u044d\u0448\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0444\u0430\u0439\u043b\u044b<\/li>\n<li>\u0432\u0430\u043c \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u043a\u044d\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f (\u0434\u0430\u043d\u043d\u0430\u044f \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0442\u044c \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0438\u0437\u0430\u0442\u043e\u0440\u044b \u0438 \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u0438)<\/li>\n<\/ul>\n<p>  <\/p>\n<p>\u041a\u043e\u0433\u0434\u0430 \u043b\u0443\u0447\u0448\u0435 \u043d\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c:<\/p>\n<p>  <\/p>\n<ul>\n<li>\u0432\u044b \u0445\u043e\u0442\u0438\u0442\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0434\u0440\u0443\u0433\u0438\u0435 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u0421\u0412 (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043f\u0443\u0448-\u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u044f)<\/li>\n<li>\u0432\u044b \u0445\u043e\u0442\u0438\u0442\u0435 \u0438\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u0441\u043a\u0440\u0438\u043f\u0442\u044b \u0438\u043b\u0438 \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u0443\u044e \u043b\u043e\u0433\u0438\u043a\u0443<\/li>\n<\/ul>\n<p>  <\/p>\n<p><strong><code>injectManifest<\/code><\/strong><\/p>\n<p>  <\/p>\n<p>\u0420\u0435\u0436\u0438\u043c <code>injectManifest<\/code> \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0431\u043e\u043b\u0435\u0435 \u043f\u043e\u043b\u043d\u044b\u0439 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u044c \u043d\u0430\u0434 \u0442\u0435\u043c, \u043a\u0430\u043a \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c \u0444\u0438\u043d\u0430\u043b\u044c\u043d\u044b\u0439 \u0421\u0412. \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u044d\u0442\u043e\u0433\u043e \u0440\u0435\u0436\u0438\u043c\u0430 \u043f\u0440\u0435\u0434\u043f\u043e\u043b\u0430\u0433\u0430\u0435\u0442 \u043d\u0430\u043b\u0438\u0447\u0438\u0435 \u0444\u0430\u0439\u043b\u0430 \u0441 \u0421\u0412 (\u0432 \u043b\u043e\u043a\u0430\u0446\u0438\u0438, \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u043e\u0439 \u0432 <code>config.js<\/code>).<\/p>\n<p>  <\/p>\n<p>\u041f\u0440\u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0435 <code>injectManifest<\/code> \u043e\u043d \u0438\u0449\u0435\u0442 \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u0443\u044e \u0441\u0442\u0440\u043e\u043a\u0443 (<code>precacheAndRoute(self.__WB_MANIFEST)<\/code> \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e) \u0432 \u043a\u043e\u0434\u0435 \u0421\u0412. \u041e\u043d \u0437\u0430\u043c\u0435\u043d\u044f\u0435\u0442 \u043f\u0443\u0441\u0442\u043e\u0439 \u043c\u0430\u0441\u0441\u0438\u0432 \u0441\u043f\u0438\u0441\u043a\u043e\u043c <code>URL<\/code> \u0434\u043b\u044f \u043f\u0440\u0435\u0434\u0432\u0430\u0440\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0433\u043e \u043a\u044d\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0438 \u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u0442 \u0421\u0412 \u0432 \u043b\u043e\u043a\u0430\u0446\u0438\u044e, \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u0443\u044e \u0432 <code>config.js<\/code>. \u041e\u0441\u0442\u0430\u043b\u044c\u043d\u043e\u0439 \u043a\u043e\u0434 \u0421\u0412 \u043e\u0441\u0442\u0430\u0435\u0442\u0441\u044f \u043d\u0435\u0438\u0437\u043c\u0435\u043d\u043d\u044b\u043c.<\/p>\n<p>  <\/p>\n<pre><code class=\"bash\">workbox injectManifest path\/to\/config.js<\/code><\/pre>\n<p>  <\/p>\n<p>\u041a\u043e\u0433\u0434\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c:<\/p>\n<p>  <\/p>\n<ul>\n<li>\u0432\u0430\u043c \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0431\u043e\u043b\u044c\u0448\u0435 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u044f \u043d\u0430\u0434 \u0421\u0412<\/li>\n<li>\u0432\u044b \u0445\u043e\u0442\u0438\u0442\u0435 \u043f\u0440\u0435\u0434\u0432\u0430\u0440\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043a\u044d\u0448\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0444\u0430\u0439\u043b\u044b<\/li>\n<li>\u0432\u0430\u043c \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0431\u043e\u043b\u044c\u0448\u0430\u044f \u0433\u0438\u0431\u043a\u043e\u0441\u0442\u044c \u0441 \u0442\u043e\u0447\u043a\u0438 \u0437\u0440\u0435\u043d\u0438\u044f \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0438\u0437\u0430\u0446\u0438\u0438<\/li>\n<li>\u0432\u044b \u0445\u043e\u0442\u0438\u0442\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0421\u0412 \u0441\u043e\u0432\u043c\u0435\u0441\u0442\u043d\u043e \u0441 \u0434\u0440\u0443\u0433\u0438\u043c\u0438 <code>API<\/code> (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0441 \u043f\u0443\u0448-\u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u044f\u043c\u0438)<\/li>\n<\/ul>\n<p>  <\/p>\n<p>\u041a\u043e\u0433\u0434\u0430 \u043b\u0443\u0447\u0448\u0435 \u043d\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c:<\/p>\n<p>  <\/p>\n<ul>\n<li>\u0432\u044b \u0438\u0449\u0435\u0442\u0435 \u0441\u0430\u043c\u044b\u0439 \u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u0441\u043f\u043e\u0441\u043e\u0431 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0421\u0412 \u0432 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435<\/li>\n<\/ul>\n<p>  <\/p>\n<p><strong><code>copyLibraries<\/code><\/strong><\/p>\n<p>  <\/p>\n<p>\u0414\u0430\u043d\u043d\u044b\u0439 \u0440\u0435\u0436\u0438\u043c \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043f\u043e\u043b\u0435\u0437\u0435\u043d, \u043a\u043e\u0433\u0434\u0430 \u0432\u044b \u0445\u043e\u0442\u0438\u0442\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0440\u0435\u0436\u0438\u043c <code>injectManifest<\/code> \u0438 \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u0443\u044e \u043a\u043e\u043f\u0438\u044e <code>WB<\/code> \u0432\u043c\u0435\u0441\u0442\u043e <code>CDN<\/code>.<\/p>\n<p>  <\/p>\n<h3 id=\"workbox-build\"><code>workbox-build<\/code><\/h3>\n<p>  <\/p>\n<p>\u0423\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430:<\/p>\n<p>  <\/p>\n<pre><code class=\"bash\">yarn add workbox-build # \u0438\u043b\u0438 npm i workbox-build<\/code><\/pre>\n<p>  <\/p>\n<p>\u0412\u044b\u0437\u044b\u0432\u0430\u0435\u043c <code>generateSW()<\/code>. \u0414\u043b\u044f \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u0421\u0412 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c <code>workboxBuild.generateSW()<\/code> \u0432 <code>Node.js-\u0441\u043a\u0440\u0438\u043f\u0442<\/code>:<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">const workboxBuild = require('workbox-build')  \/\/ \u041e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435: \u044d\u0442\u043e \u0434\u043e\u043b\u0436\u043d\u043e \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c\u0441\u044f \u043f\u043e\u0441\u043b\u0435 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0432\u0441\u0435\u0445 \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432 const buildSW = () =&gt; {   \/\/ \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442\u0441\u044f \u043f\u0440\u043e\u043c\u0438\u0441   return workboxBuild.generateSW({     globDirectory: 'build',     globPatterns: ['**\/*.{html,json,js,css}'],     swDest: 'build\/sw.js'   }) }<\/code><\/pre>\n<p>  <\/p>\n<p>\u042d\u0442\u043e\u0442 \u043a\u043e\u0434 \u0441\u043e\u0437\u0434\u0430\u0441\u0442 \u0421\u0412 \u0432 <code>build\/sw.js<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u0440\u0435\u0434\u0432\u0430\u0440\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043a\u044d\u0448\u0438\u0440\u0443\u0435\u0442 \u0432\u0441\u0435 \u0444\u0430\u0439\u043b\u044b \u0432 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u0438 <code>build<\/code>, \u0441\u043e\u0432\u043f\u0430\u0434\u0430\u044e\u0449\u0438\u0435 \u0441 <code>globPatterns<\/code>.<\/p>\n<p>  <\/p>\n<p>\u0420\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u0443\u0435\u043c \u0421\u0412 \u043d\u0430 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0435:<\/p>\n<p>  <\/p>\n<pre><code class=\"html\">&lt;script&gt;   if ('serviceWorker' in navigator) {     window.addEventListener('load', () =&gt; {       navigator.serviceWorker.register('\/service-worker.js')     })   } &lt;\/script&gt;<\/code><\/pre>\n<p>  <\/p>\n<p>\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 \u0421\u0412 \u0434\u043b\u044f \u043a\u044d\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0439 \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0438\u0434\u0435\u043d\u0442\u0438\u0447\u043d\u0430 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0435, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u043e\u0439 \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0421\u0412 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e <code>workbox-cli<\/code>.<\/p>\n<p>  <\/p>\n<p>\u041c\u043e\u0434\u0443\u043b\u044c <code>workbox-build<\/code> \u0438\u043d\u0442\u0435\u0433\u0440\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0432 \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u0441\u0431\u043e\u0440\u043a\u0438 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e <code>Node.js<\/code> \u0438 \u043c\u043e\u0436\u0435\u0442 \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0433\u043e\u0442\u043e\u0432\u044b\u0439 \u0421\u0412 \u0438\u043b\u0438 \u0444\u043e\u0440\u043c\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0441\u043f\u0438\u0441\u043e\u043a \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432 \u0434\u043b\u044f \u043f\u0440\u0435\u0434\u0432\u0430\u0440\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0433\u043e \u043a\u044d\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u043c \u0421\u0412.<\/p>\n<p>  <\/p>\n<p><strong><code>generateSW<\/code><\/strong><\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">\/\/ \u0432 build.js const { generateSW } = require('workbox-build')  const swDest = 'build\/sw.js' generateSW({   swDest,   \/\/ \u0434\u0440\u0443\u0433\u0438\u0435 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 }).then(({ count, size }) =&gt; {   console.log(     `\u0421\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d ${swDest}, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u0440\u0435\u0434\u0432\u0430\u0440\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043a\u044d\u0448\u0438\u0440\u0443\u0435\u0442 ${count} \u0444\u0430\u0439\u043b\u043e\u0432. \u041e\u0431\u0449\u0438\u0439 \u0440\u0430\u0437\u043c\u0435\u0440 \u043a\u044d\u0448\u0438\u0440\u0443\u0435\u043c\u044b\u0445 \u0444\u0430\u0439\u043b\u043e\u0432 \u0441\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 ${size} \u0431\u0430\u0439\u0442.`   ) })<\/code><\/pre>\n<p>  <\/p>\n<p><strong><code>injectManifest<\/code><\/strong><\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">\/\/ \u0432 build.js const { injectManifest } = require('workbox-build')  const swSrc = 'src\/sw.js' const swDest = 'build\/sw.js' injectManifest({   swSrc,   swDest,   \/\/ \u0434\u0440\u0443\u0433\u0438\u0435 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 }).then(({ count, size }) =&gt; {   console.log(     `\u0421\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d ${swDest}, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u0440\u0435\u0434\u0432\u0430\u0440\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043a\u044d\u0448\u0438\u0440\u0443\u0435\u0442 ${count} \u0444\u0430\u0439\u043b\u043e\u0432. \u041e\u0431\u0449\u0438\u0439 \u0440\u0430\u0437\u043c\u0435\u0440 \u043a\u044d\u0448\u0438\u0440\u0443\u0435\u043c\u044b\u0445 \u0444\u0430\u0439\u043b\u043e\u0432 \u0441\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 ${size} \u0431\u0430\u0439\u0442.`   ) })<\/code><\/pre>\n<p>  <\/p>\n<h3 id=\"webpack\"><code>Webpack<\/code><\/h3>\n<p>  <\/p>\n<p><code>WB<\/code> \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0434\u0432\u0430 \u043f\u043b\u0430\u0433\u0438\u043d\u0430 \u0434\u043b\u044f \u0432\u0435\u0431\u043f\u0430\u043a\u0430: \u043e\u0434\u0438\u043d \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0433\u043e\u0442\u043e\u0432\u043e\u0433\u043e \u0421\u0412, \u0434\u0440\u0443\u0433\u043e\u0439 \u0434\u043b\u044f \u0444\u043e\u0440\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0441\u043f\u0438\u0441\u043a\u0430 \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432 \u0434\u043b\u044f \u043f\u0440\u0435\u0434\u0432\u0430\u0440\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0433\u043e \u043a\u044d\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f.<\/p>\n<p>  <\/p>\n<p>\u042d\u0442\u0438 \u043f\u043b\u0430\u0433\u0438\u043d\u044b \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u044b \u0432 \u0432\u0438\u0434\u0435 \u0434\u0432\u0443\u0445 \u043a\u043b\u0430\u0441\u0441\u043e\u0432 \u0432 \u043c\u043e\u0434\u0443\u043b\u0435 <code>workbox-webpack-plugin<\/code>: <code>GenerateSW<\/code> \u0438 <code>InjectManifest<\/code>.<\/p>\n<p>  <\/p>\n<p><strong><code>GenerateSW<\/code><\/strong><\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">\/\/ \u0432 webpack.config.js: const { GenerateSW } = require('workbox-webpack-plugin')  module.exports = {   \/\/ \u0434\u0440\u0443\u0433\u0438\u0435 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u0432\u0435\u0431\u043f\u0430\u043a\u0430   plugins: [     \/\/ \u0434\u0440\u0443\u0433\u0438\u0435 \u043f\u043b\u0430\u0433\u0438\u043d\u044b     new GenerateSW({       \/\/ \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438       option: 'value'     })   ] }<\/code><\/pre>\n<p>  <\/p>\n<p><strong><code>InjectManifest<\/code><\/strong><\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">\/\/ \u0432 webpack.config.js: const { InjectManifest } = require('workbox-webpack-plugin')  module.exports = {   plugins: [     new InjectManifest({       swSrc: '.\/src\/sw.js'     })   ] }<\/code><\/pre>\n<p>  <\/p>\n<p>\u041d\u0430 \u044d\u0442\u043e\u043c \u043f\u0435\u0440\u0432\u0430\u044f \u0447\u0430\u0441\u0442\u044c \u0440\u0443\u043a\u043e\u0432\u043e\u0434\u0441\u0442\u0432\u0430 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0430. \u0412 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0439 \u0447\u0430\u0441\u0442\u0438 \u043c\u044b \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0431\u043e\u043b\u044c\u0448\u0438\u043d\u0441\u0442\u0432\u043e \u043c\u043e\u0434\u0443\u043b\u0435\u0439, \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u043c\u044b\u0445 <code>WB<\/code>, \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0430\u0435\u043c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0441\u043d\u0438\u043f\u043f\u0435\u0442\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u043e\u0436\u043d\u043e \u0431\u0443\u0434\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0432 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f\u0445 \u201c\u043a\u0430\u043a \u0435\u0441\u0442\u044c\u201d, \u0430 \u0442\u0430\u043a\u0436\u0435 \u043a\u0440\u0430\u0442\u043a\u043e \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0433\u043e\u0442\u043e\u0432\u044b\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u044f \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f <code>PWA<\/code>, \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u043c\u044b\u0435 \u0442\u0430\u043a\u0438\u043c\u0438 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u0430\u043c\u0438 \u0434\u043b\u044f \u0444\u0440\u043e\u043d\u0442\u0435\u043d\u0434\u0430 \u043a\u0430\u043a <code>React<\/code> \u0438 <code>Vue<\/code>.<\/p>\n<p>  <\/p>\n<hr>\n<p>  <\/p>\n<p><a href=\"https:\/\/macloud.ru\/?partner=4189mjxpzx\">VPS<\/a> \u0441\u0435\u0440\u0432\u0435\u0440\u044b \u043e\u0442 \u041c\u0430\u043a\u043b\u0430\u0443\u0434 \u0431\u044b\u0441\u0442\u0440\u044b\u0435 \u0438 \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u044b\u0435.<\/p>\n<p>  <\/p>\n<p>\u0417\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u0443\u0439\u0442\u0435\u0441\u044c \u043f\u043e \u0441\u0441\u044b\u043b\u043a\u0435 \u0432\u044b\u0448\u0435 \u0438\u043b\u0438 \u043a\u043b\u0438\u043a\u043d\u0443\u0432 \u043d\u0430 \u0431\u0430\u043d\u043d\u0435\u0440 \u0438 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u0435 10% \u0441\u043a\u0438\u0434\u043a\u0443 \u043d\u0430 \u043f\u0435\u0440\u0432\u044b\u0439 \u043c\u0435\u0441\u044f\u0446 \u0430\u0440\u0435\u043d\u0434\u044b \u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u043b\u044e\u0431\u043e\u0439 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438!<\/p>\n<p>  <\/p>\n<p><a href=\"https:\/\/macloud.ru\/?partner=4189mjxpzx&amp;utm_source=habr&amp;utm_medium=original&amp;utm_campaign=igor\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/et\/1a\/yp\/et1aypandyuamqprsz3m2ntm4ky.png\"><\/a><\/p>\n<\/div>\n<p> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/company\/macloud\/blog\/563684\/\"> https:\/\/habr.com\/ru\/company\/macloud\/blog\/563684\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"\n<div class=\"post__text post__text-html post__text_v1\" id=\"post-content-body\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/q3\/h3\/mw\/q3h3mwmy5zsl-8i3svvhojkmyww.png\">  <\/p>\n<h2 id=\"chto-takoe-workbox\">\u0427\u0442\u043e \u0442\u0430\u043a\u043e\u0435 <code>Workbox<\/code>?<\/h2>\n<p>  <\/p>\n<p><a href=\"https:\/\/developers.google.com\/web\/tools\/workbox\"><code>Workbox<\/code><\/a> (\u0434\u0430\u043b\u0435\u0435 \u2014 <code>WB<\/code>) \u2014 \u044d\u0442\u043e \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 (\u0442\u043e\u0447\u043d\u0435\u0435, \u043d\u0430\u0431\u043e\u0440 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a), \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0439 \u0446\u0435\u043b\u044c\u044e \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f &quot;\u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043b\u0443\u0447\u0448\u0438\u0445 \u043f\u0440\u0430\u043a\u0442\u0438\u043a \u0438 \u0438\u0437\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043e\u0442 \u0448\u0430\u0431\u043b\u043e\u043d\u043d\u043e\u0433\u043e \u043a\u043e\u0434\u0430 \u043f\u0440\u0438 \u0440\u0430\u0431\u043e\u0442\u0435 \u0441 \u0441\u0435\u0440\u0432\u0438\u0441-\u0432\u043e\u0440\u043a\u0435\u0440\u0430\u043c\u0438&quot; (\u0434\u0430\u043b\u0435\u0435 \u2014 \u0421\u0412).<\/p>\n<p>  <\/p>\n<p>\u0415\u0441\u043b\u0438 \u0432\u044b \u0432\u043f\u0435\u0440\u0432\u044b\u0435 \u0441\u043b\u044b\u0448\u0438\u0442\u0435 \u043e \u0421\u0412, \u0442\u043e \u043f\u0435\u0440\u0435\u0434 \u0438\u0437\u0443\u0447\u0435\u043d\u0438\u0435\u043c \u0434\u0430\u043d\u043d\u043e\u0433\u043e \u0440\u0443\u043a\u043e\u0432\u043e\u0434\u0441\u0442\u0432\u0430 \u043d\u0430\u0441\u0442\u043e\u044f\u0442\u0435\u043b\u044c\u043d\u043e \u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0443\u0435\u0442\u0441\u044f \u043e\u0437\u043d\u0430\u043a\u043e\u043c\u0438\u0442\u044c\u0441\u044f \u0441\u043e \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c\u0438 \u043c\u0430\u0442\u0435\u0440\u0438\u0430\u043b\u0430\u043c\u0438:<\/p>\n<p>  <\/p>\n<ul>\n<li><a href=\"https:\/\/developer.mozilla.org\/ru\/docs\/Web\/API\/Service_Worker_API\">Service Worker API \u2014 MDN<\/a><\/li>\n<li><a href=\"https:\/\/developers.google.com\/web\/fundamentals\/primers\/service-workers\">Service Workers: an Introduction \u2014 Web Fundamentals<\/a><\/li>\n<li><a href=\"https:\/\/habr.com\/ru\/post\/491840\/\">\u0412\u0438\u0437\u0443\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441\u0435\u0440\u0432\u0438\u0441-\u0432\u043e\u0440\u043a\u0435\u0440\u043e\u0432 \u2014 \u0425\u0430\u0431\u0440<\/a><\/li>\n<li><a href=\"https:\/\/habr.com\/ru\/post\/517672\/\">\u0420\u0435\u0446\u0435\u043f\u0442\u044b \u043f\u043e \u043f\u0440\u0438\u0433\u043e\u0442\u043e\u0432\u043b\u0435\u043d\u0438\u044e \u043e\u0444\u043b\u0430\u0439\u043d-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439 \u2014 \u0425\u0430\u0431\u0440<\/a><\/li>\n<\/ul>\n<p>  <\/p>\n<p><code>WB<\/code> \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438:<\/p>\n<p>  <\/p>\n<ul>\n<li>\u043f\u0440\u0435\u0434\u0432\u0430\u0440\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0435 \u043a\u044d\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435<\/li>\n<li>\u043a\u044d\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f<\/li>\n<li>\u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u0438 (\u043a\u044d\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f)<\/li>\n<li>\u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 (\u043f\u0435\u0440\u0435\u0445\u0432\u0430\u0442 \u0441\u0435\u0442\u0435\u0432\u044b\u0445) \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432<\/li>\n<li>\u0444\u043e\u043d\u043e\u0432\u0430\u044f \u0441\u0438\u043d\u0445\u0440\u043e\u043d\u0438\u0437\u0430\u0446\u0438\u044f<\/li>\n<li>\u043f\u043e\u043c\u043e\u0449\u044c \u0432 \u043e\u0442\u043b\u0430\u0434\u043a\u0435<\/li>\n<\/ul>\n<p>  <\/p>\n<h2 id=\"na-chto-pohozh-wb-api\">\u041d\u0430 \u0447\u0442\u043e \u043f\u043e\u0445\u043e\u0436 <code>WB API<\/code>?<\/h2>\n<p>  <\/p>\n<p>\u041d\u0438\u0436\u0435 \u043f\u0440\u0438\u0432\u0435\u0434\u0435\u043d\u044b \u043f\u0440\u0438\u043c\u0435\u0440\u044b \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0445 \u043f\u043e\u0434\u0445\u043e\u0434\u043e\u0432 \u043a \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0435 \u043f\u0440\u043e\u0433\u0440\u0435\u0441\u0441\u0438\u0432\u043d\u044b\u0445 \u0432\u0435\u0431-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439 (\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439, \u0432 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442\u0441\u044f \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438, \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u043c\u044b\u0435 \u0421\u0412).<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-325203","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/325203","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=325203"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/325203\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=325203"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=325203"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=325203"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}