{"id":325219,"date":"2021-06-21T09:00:08","date_gmt":"2021-06-21T09:00:08","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=325219"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=325219","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 2"},"content":{"rendered":"\n<div class=\"post__text post__text-html post__text_v1\" id=\"post-content-body\">\n<p><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/q3\/h3\/mw\/q3h3mwmy5zsl-8i3svvhojkmyww.png\" alt=\"image\"><\/p>\n<p>  <\/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<p>\u042d\u0442\u043e \u0432\u0442\u043e\u0440\u0430\u044f \u0447\u0430\u0441\u0442\u044c \u0440\u0443\u043a\u043e\u0432\u043e\u0434\u0441\u0442\u0432\u0430. \u0412\u043e\u0442 \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043f\u0435\u0440\u0432\u0443\u044e \u0447\u0430\u0441\u0442\u044c.<\/p>\n<p>  <\/p>\n<h2 id=\"moduli-predostavlyaemye-wb\">\u041c\u043e\u0434\u0443\u043b\u0438, \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u043c\u044b\u0435 <code>WB<\/code><\/h2>\n<p><a name=\"habracut\"><\/a>  <\/p>\n<p>\u041a\u0430\u0436\u0434\u044b\u0439 \u043c\u043e\u0434\u0443\u043b\u044c \u0440\u0435\u0448\u0430\u0435\u0442 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u0443\u044e \u0437\u0430\u0434\u0430\u0447\u0443 \u0438 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d \u043a\u0430\u043a \u0441\u043e\u0432\u043c\u0435\u0441\u0442\u043d\u043e \u0441 \u0434\u0440\u0443\u0433\u0438\u043c\u0438 \u043c\u043e\u0434\u0443\u043b\u044f\u043c\u0438, \u0442\u0430\u043a \u0438 \u0441\u0430\u043c\u043e\u0441\u0442\u043e\u044f\u0442\u0435\u043b\u044c\u043d\u043e.<\/p>\n<p>  <\/p>\n<ul>\n<li><code>workbox-background-sync<\/code>: \u0444\u043e\u043d\u043e\u0432\u0430\u044f \u0441\u0438\u043d\u0445\u0440\u043e\u043d\u0438\u0437\u0430\u0446\u0438\u044f, \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0449\u0430\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c \u0441\u0435\u0442\u0435\u0432\u044b\u0435 \u0437\u0430\u043f\u0440\u043e\u0441\u044b \u0432 \u0440\u0435\u0436\u0438\u043c\u0435 \u043e\u0444\u043b\u0430\u0439\u043d<\/li>\n<li><a href=\"https:\/\/developers.google.com\/web\/tools\/workbox\/modules\/workbox-broadcast-update\"><code>workbox-broadcast-update<\/code><\/a>: \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0430 \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u0439 \u043e\u0431 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0438 \u043a\u044d\u0448\u0430 (\u0447\u0435\u0440\u0435\u0437 <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/API\/Broadcast_Channel_API\"><code>Broadcast Channel API<\/code><\/a>)<\/li>\n<li><code>workbox-cacheable-response<\/code>: \u0444\u0438\u043b\u044c\u0442\u0440\u0430\u0446\u0438\u044f \u043a\u044d\u0448\u0438\u0440\u0443\u0435\u043c\u044b\u0445 \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 \u0438\u043b\u0438 \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043a\u043e\u0432 \u043e\u0442\u0432\u0435\u0442\u043e\u0432<\/li>\n<li><a href=\"https:\/\/developers.google.com\/web\/tools\/workbox\/modules\/workbox-core\"><code>workbox-core<\/code><\/a>: \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0435 \u0443\u0440\u043e\u0432\u043d\u044f \u043b\u043e\u0433\u0433\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0438 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0439 \u043a\u044d\u0448\u0430. \u0421\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u043e\u0431\u0449\u0438\u0439 \u043a\u043e\u0434, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u044b\u0439 \u0434\u0440\u0443\u0433\u0438\u043c\u0438 \u043c\u043e\u0434\u0443\u043b\u044f\u043c\u0438<\/li>\n<li><code>workbox-expiration<\/code>: \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430 \u043b\u0438\u043c\u0438\u0442\u0430 \u0437\u0430\u043f\u0438\u0441\u0435\u0439 \u0432 \u043a\u044d\u0448\u0435 \u0438 \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u0436\u0438\u0437\u043d\u0438 \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u043d\u044b\u0445 \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432<\/li>\n<li><a href=\"https:\/\/developers.google.com\/web\/tools\/workbox\/modules\/workbox-google-analytics\"><code>workbox-google-analytics<\/code><\/a>: \u0444\u0438\u043a\u0441\u0430\u0446\u0438\u044f \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0439 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439 \u043d\u0430 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0435 \u0432 \u0440\u0435\u0436\u0438\u043c\u0435 \u043e\u0444\u043b\u0430\u0439\u043d<\/li>\n<li><a href=\"https:\/\/developers.google.com\/web\/tools\/workbox\/modules\/workbox-navigation-preload\"><code>workbox-navigation-preload<\/code><\/a>: \u043f\u0440\u0435\u0434\u0432\u0430\u0440\u0438\u0442\u0435\u043b\u044c\u043d\u0430\u044f \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0430 \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432, \u0441\u0432\u044f\u0437\u0430\u043d\u043d\u044b\u0445 \u0441 \u043d\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u0435\u0439<\/li>\n<li><code>workbox-precaching<\/code>: \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 \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432 \u0438 \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0438\u0445 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435\u043c<\/li>\n<li><a href=\"https:\/\/developers.google.com\/web\/tools\/workbox\/modules\/workbox-range-requests\"><code>workbox-range-request<\/code><\/a>: \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0430 \u0447\u0430\u0441\u0442\u0438\u0447\u043d\u044b\u0445 \u043e\u0442\u0432\u0435\u0442\u043e\u0432<\/li>\n<li><code>workbox-recipes<\/code>: \u043e\u0431\u0449\u0438\u0435 \u043f\u0430\u0442\u0442\u0435\u0440\u043d\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f <code>WB<\/code><\/li>\n<li><code>workbox-routing<\/code>: \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u044b\u0445 \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u0439 \u043a\u044d\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0438\u043b\u0438 \u043a\u043e\u043b\u0431\u044d\u043a\u043e\u0432<\/li>\n<li><code>workbox-strategies<\/code>: \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\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, \u043a\u0430\u043a \u043f\u0440\u0430\u0432\u0438\u043b\u043e, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u044b\u0435 \u0441\u043e\u0432\u043c\u0435\u0441\u0442\u043d\u043e \u0441 <code>workbox-routing<\/code><\/li>\n<li><a href=\"https:\/\/developers.google.com\/web\/tools\/workbox\/reference-docs\/latest\/module-workbox-streams\"><code>workbox-streams<\/code><\/a>: \u0444\u043e\u0440\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043e\u0442\u0432\u0435\u0442\u0430 \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u043e\u0432 \u043f\u043e\u0442\u043e\u043a\u043e\u0432\u043e\u0439 \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0438 \u0434\u0430\u043d\u043d\u044b\u0445<\/li>\n<li><code>workbox-window<\/code>: \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u044f, \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435\u043c \u0438 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u0441\u043e\u0431\u044b\u0442\u0438\u0439 \u0436\u0438\u0437\u043d\u0435\u043d\u043d\u043e\u0433\u043e \u0446\u0438\u043a\u043b\u0430 \u0421\u0412<\/li>\n<\/ul>\n<p>  <\/p>\n<h2 id=\"workbox-background-sync\"><code>workbox-background-sync<\/code><\/h2>\n<p>  <\/p>\n<p>\u0418\u043d\u043e\u0433\u0434\u0430 \u0437\u0430\u043f\u0440\u043e\u0441 \u043d\u0430 \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0443 \u0434\u0430\u043d\u043d\u044b\u0445 \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440 \u043f\u0440\u043e\u0432\u0430\u043b\u0438\u0432\u0430\u0435\u0442\u0441\u044f. \u042d\u0442\u043e \u043c\u043e\u0436\u0435\u0442 \u043f\u0440\u043e\u0438\u0437\u043e\u0439\u0442\u0438 \u0438\u0437-\u0437\u0430 \u043f\u043e\u0442\u0435\u0440\u0438 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u044f \u0438\u043b\u0438 \u0438\u0437-\u0437\u0430 &quot;\u0443\u043f\u0430\u0432\u0448\u0435\u0433\u043e&quot; \u0441\u0435\u0440\u0432\u0435\u0440\u0430. \u0412 \u043b\u044e\u0431\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435, \u0431\u044b\u043b\u043e \u0431\u044b \u0437\u0434\u043e\u0440\u043e\u0432\u043e \u0438\u043c\u0435\u0442\u044c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u043f\u043e\u0432\u0442\u043e\u0440\u044f\u0442\u044c \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u0442\u0430\u043a\u043e\u0433\u043e \u0437\u0430\u043f\u0440\u043e\u0441\u0430.<\/p>\n<p>  <\/p>\n<p>\u041d\u043e\u0432\u044b\u0439 <a href=\"https:\/\/wicg.github.io\/background-sync\/spec\/\"><code>BackgroundSync API<\/code><\/a> \u2014 \u043e\u0442\u043b\u0438\u0447\u043d\u043e\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u0434\u043b\u044f \u0442\u0430\u043a\u043e\u0439 \u0441\u0438\u0442\u0443\u0430\u0446\u0438\u0438. \u041a\u043e\u0433\u0434\u0430 \u0421\u0412 \u043e\u0431\u043d\u0430\u0440\u0443\u0436\u0438\u0432\u0430\u0435\u0442 \u043f\u0440\u043e\u0432\u0430\u043b\u0438\u0432\u0448\u0438\u0439\u0441\u044f \u0437\u0430\u043f\u0440\u043e\u0441, \u043e\u043d \u043c\u043e\u0436\u0435\u0442 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0432\u043e\u0437\u043d\u0438\u043a\u043d\u043e\u0432\u0435\u043d\u0438\u0435 \u0441\u043e\u0431\u044b\u0442\u0438\u044f <code>sync<\/code>, \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u043c\u043e\u0433\u043e \u0431\u0440\u0443\u0437\u0435\u0440\u043e\u043c \u043f\u0440\u0438 \u0432\u043e\u0441\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0438 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u044f. \u0414\u0430\u043d\u043d\u043e\u0435 \u0441\u043e\u0431\u044b\u0442\u0438\u0435 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0434\u0430\u0436\u0435 \u0435\u0441\u043b\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0432\u044b\u0448\u0435\u043b \u0438\u0437 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f, \u0447\u0442\u043e \u0434\u0435\u043b\u0430\u0435\u0442 \u044d\u0442\u043e\u0442 \u043f\u043e\u0434\u0445\u043e\u0434 \u0433\u043e\u0440\u0430\u0437\u0434\u043e \u0431\u043e\u043b\u0435\u0435 \u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u044b\u043c, \u0447\u0435\u043c \u0442\u0440\u0430\u0434\u0438\u0446\u0438\u043e\u043d\u043d\u044b\u0435 \u0441\u043f\u043e\u0441\u043e\u0431\u044b \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u043e\u0433\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u043f\u0440\u043e\u0432\u0430\u043b\u0438\u0432\u0448\u0438\u0445\u0441\u044f \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432.<\/p>\n<p>  <\/p>\n<p>\u0411\u0440\u0430\u0443\u0437\u0435\u0440\u044b, \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u044e\u0449\u0438\u0435 <code>BackgroundSync API<\/code>, \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u044e\u0442 \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u044b\u0439 \u0437\u0430\u043f\u0440\u043e\u0441 \u043e\u0442 \u0432\u0430\u0448\u0435\u0433\u043e \u0438\u043c\u0435\u043d\u0438 \u0447\u0435\u0440\u0435\u0437 \u0438\u043d\u0442\u0435\u0440\u0432\u0430\u043b, \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u043c\u044b\u0439 \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u043e\u043c. \u0412 \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0430\u0445, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043d\u0435 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u044e\u0442 \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u0443\u044e \u0442\u0435\u0445\u043d\u043e\u043b\u043e\u0433\u0438\u044e, \u0440\u0430\u0441\u0441\u043c\u0430\u0442\u0440\u0438\u0432\u0430\u0435\u043c\u044b\u0439 \u043c\u043e\u0434\u0443\u043b\u044c \u043e\u0442\u043f\u0440\u0430\u0432\u0438\u0442 \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u044b\u0439 \u0437\u0430\u043f\u0440\u043e\u0441 \u043f\u0440\u0438 \u043e\u0447\u0435\u0440\u0435\u0434\u043d\u043e\u043c \u0437\u0430\u043f\u0443\u0441\u043a\u0435 \u0421\u0412.<\/p>\n<p>  <\/p>\n<h3 id=\"bazovoe-ispolzovanie\">\u0411\u0430\u0437\u043e\u0432\u043e\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435<\/h3>\n<p>  <\/p>\n<p>\u041f\u0440\u043e\u0441\u0442\u0435\u0439\u0448\u0438\u0439 \u0441\u043f\u043e\u0441\u043e\u0431 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0444\u043e\u043d\u043e\u0432\u043e\u0439 \u0441\u0438\u043d\u0445\u0440\u043e\u043d\u0438\u0437\u0430\u0446\u0438\u0438 \u0437\u0430\u043a\u043b\u044e\u0447\u0430\u0435\u0442\u0441\u044f \u0432 \u043f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u0438\u0438 \u043f\u043b\u0430\u0433\u0438\u043d\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u043f\u043e\u043c\u0435\u0449\u0430\u0435\u0442 \u043f\u0440\u043e\u0432\u0430\u043b\u0438\u0432\u0448\u0438\u0435\u0441\u044f \u0437\u0430\u043f\u0440\u043e\u0441\u044b \u0432 \u043e\u0447\u0435\u0440\u0435\u0434\u044c \u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442 \u0438\u0445 \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u0443\u044e \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0443 \u043f\u0440\u0438 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u0438 \u0441\u043e\u0431\u044b\u0442\u0438\u044f <code>sync<\/code>:<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">import { BackgroundSyncPlugin } from 'workbox-background-sync' import { registerRoute } from 'workbox-routing' import { NetworkOnly } from 'workbox-strategies'  const bgSyncPlugin = new BackgroundSyncPlugin('myQueueName', {   maxRetentionTime: 24 * 60, \/\/ \u041f\u043e\u043f\u044b\u0442\u043a\u0430 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u043e\u0433\u043e \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0430 \u0432 \u0442\u0435\u0447\u0435\u043d\u0438\u0435 24 \u0447\u0430\u0441\u043e\u0432 (\u0432 \u043c\u0438\u043d\u0443\u0442\u0430\u0445) })  registerRoute(   \/\\\/api\\\/.*\\\/*.json\/,   new NetworkOnly({     plugins: [bgSyncPlugin],   }),   'POST' )<\/code><\/pre>\n<p>  <\/p>\n<h3 id=\"prodvinutoe-ispolzovanie\">\u041f\u0440\u043e\u0434\u0432\u0438\u043d\u0443\u0442\u043e\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435<\/h3>\n<p>  <\/p>\n<p>\u0420\u0430\u0441\u0441\u043c\u0430\u0442\u0440\u0438\u0432\u0430\u0435\u043c\u044b\u0439 \u043c\u043e\u0434\u0443\u043b\u044c \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u043a\u043b\u0430\u0441\u0441 <code>Queue<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439, \u043f\u043e\u0441\u043b\u0435 \u0438\u043d\u0441\u0442\u0430\u043d\u0446\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f, \u043c\u043e\u0436\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0434\u043b\u044f \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u043f\u0440\u043e\u0432\u0430\u043b\u0438\u0432\u0448\u0438\u0445\u0441\u044f \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432. \u0422\u0430\u043a\u0438\u0435 \u0437\u0430\u043f\u0440\u043e\u0441\u044b \u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u0432 <a href=\"https:\/\/developer.mozilla.org\/ru\/docs\/Web\/API\/IndexedDB_API\"><code>IndexedDB<\/code><\/a> \u0438 \u0438\u0437\u0432\u043b\u0435\u043a\u0430\u044e\u0442\u0441\u044f \u0438\u0437 \u043d\u0435\u0435 \u043f\u0440\u0438 \u0432\u043e\u0441\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0438 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u044f.<\/p>\n<p>  <\/p>\n<p><strong>\u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u043e\u0447\u0435\u0440\u0435\u0434\u0438<\/strong><\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">import { Queue } from 'workbox-background-sync'  const queue = new Queue('myQueueName') \/\/ \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u043e\u0447\u0435\u0440\u0435\u0434\u0438 \u0434\u043e\u043b\u0436\u043d\u043e \u0431\u044b\u0442\u044c \u0443\u043d\u0438\u043a\u0430\u043b\u044c\u043d\u044b\u043c<\/code><\/pre>\n<p>  <\/p>\n<p>\u041d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u043e\u0447\u0435\u0440\u0435\u0434\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u043a\u0430\u043a \u0447\u0430\u0441\u0442\u044c \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u044f &quot;\u0442\u0435\u0433\u0430&quot;, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442 <a href=\"https:\/\/wicg.github.io\/background-sync\/spec\/#dom-syncmanager-register\"><code>register()<\/code><\/a> \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u043e\u0433\u043e <a href=\"https:\/\/wicg.github.io\/background-sync\/spec\/#sync-manager-interface\"><code>SyncManager<\/code><\/a>. \u041e\u043d\u043e \u0442\u0430\u043a\u0436\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u043a\u0430\u043a \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/API\/IDBObjectStore\">&quot;\u043e\u0431\u044a\u0435\u043a\u0442\u043d\u043e\u0433\u043e \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0430&quot;<\/a> <code>IndexedDB<\/code>.<\/p>\n<p>  <\/p>\n<p><strong>\u0414\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u0432 \u043e\u0447\u0435\u0440\u0435\u0434\u044c<\/strong><\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">import { Queue } from 'workbox-background-sync'  const queue = new Queue('myQueueName')  self.addEventListener('fetch', (event) =&gt; {   \/\/ \u041a\u043b\u043e\u043d\u0438\u0440\u0443\u0435\u043c \u0437\u0430\u043f\u0440\u043e\u0441 \u0434\u043b\u044f \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e\u0433\u043e \u0447\u0442\u0435\u043d\u0438\u044f   \/\/ \u043f\u0440\u0438 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0438 \u0432 \u043e\u0447\u0435\u0440\u0435\u0434\u044c   const promiseChain = fetch(event.request.clone()).catch((err) =&gt; {     return queue.pushRequest({ request: event.request })   })    event.waitUntil(promiseChain) })<\/code><\/pre>\n<p>  <\/p>\n<p>\u041f\u043e\u0441\u043b\u0435 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0432 \u043e\u0447\u0435\u0440\u0435\u0434\u044c, \u0437\u0430\u043f\u0440\u043e\u0441 \u0431\u0443\u0434\u0435\u0442 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u043e \u043f\u0440\u0438 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0438 \u0421\u0412 \u0441\u043e\u0431\u044b\u0442\u0438\u044f <code>sync<\/code> (\u0438\u043b\u0438 \u043f\u0440\u0438 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u043c \u0437\u0430\u043f\u0443\u0441\u043a\u0435 \u0421\u0412 \u0432 \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0430\u0445, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043d\u0435 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u044e\u0442 \u0444\u043e\u043d\u043e\u0432\u0443\u044e \u0441\u0438\u043d\u0445\u0440\u043e\u043d\u0438\u0437\u0430\u0446\u0438\u044e).<\/p>\n<p>  <\/p>\n<h2 id=\"workbox-cacheable-response\"><code>workbox-cacheable-response<\/code><\/h2>\n<p>  <\/p>\n<p>\u041f\u0440\u0438 \u043a\u044d\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0438 \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432 \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u043d\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 \u043e\u0431\u0449\u0435\u0433\u043e \u043f\u0440\u0430\u0432\u0438\u043b\u0430 \u0434\u043b\u044f \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u044f \u0432\u0430\u043b\u0438\u0434\u043d\u043e\u0441\u0442\u0438 \u0442\u0430\u043a\u0438\u0445 \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432, \u0442.\u0435. \u0442\u043e\u0433\u043e, \u043f\u043e\u0434\u043b\u0435\u0436\u0430\u0442 \u043b\u0438 \u044d\u0442\u0438 \u0440\u0435\u0441\u0443\u0440\u0441\u044b \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044e \u0441 \u0446\u0435\u043b\u044c\u044e \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u043e\u0433\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f.<\/p>\n<p>  <\/p>\n<p>\u0420\u0430\u0441\u0441\u043c\u0430\u0442\u0440\u0438\u0432\u0430\u0435\u043c\u044b\u0439 \u043c\u043e\u0434\u0443\u043b\u044c \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0442\u044c \u043f\u0440\u0438\u0433\u043e\u0434\u043d\u043e\u0441\u0442\u044c \u043e\u0442\u0432\u0435\u0442\u0430 \u0434\u043b\u044f \u043a\u044d\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u0441\u0442\u0430\u0442\u0443\u0441-\u043a\u043e\u0434\u0430 \u0438\u043b\u0438 \u043f\u0440\u0438\u0441\u0443\u0442\u0441\u0442\u0432\u0438\u044f \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043a\u0430 \u0441 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u044b\u043c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435\u043c.<\/p>\n<p>  <\/p>\n<h3 id=\"keshirovanie-na-osnove-status-koda\">\u041a\u044d\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u0441\u0442\u0430\u0442\u0443\u0441-\u043a\u043e\u0434\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'  registerRoute(   ({ url }) =&gt;     url.origin === 'https:\/\/example.com' &amp;&amp; url.pathname.startsWith('\/images\/'),   new CacheFirst({     cacheName: 'image-cache',     plugins: [       new CacheableResponsePlugin({         statuses: [0, 200]       })     ]   }) )<\/code><\/pre>\n<p>  <\/p>\n<p>\u0414\u0430\u043d\u043d\u0430\u044f \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442 <code>WB<\/code> \u043a\u044d\u0448\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043b\u044e\u0431\u044b\u0435 \u043e\u0442\u0432\u0435\u0442\u044b \u0441\u043e \u0441\u0442\u0430\u0442\u0443\u0441\u043e\u043c <code>0<\/code> \u0438\u043b\u0438 <code>200<\/code> \u043f\u0440\u0438 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0435 \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 \u043a <code>https:\/\/example.com<\/code>.<\/p>\n<p>  <\/p>\n<h3 id=\"keshirovanie-na-osnove-zagolovka\">\u041a\u044d\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043a\u0430<\/h3>\n<p>  <\/p>\n<pre><code class=\"plaintext\">import { registerRoute } from 'workbox-routing' import { StaleWhileRevalidate } from 'workbox-strategies' import { CacheableResponsePlugin } from 'workbox-cacheable-response'  registerRoute(   ({ url }) =&gt; url.pathname.startsWith('\/path\/to\/api\/'),   new StaleWhileRevalidate({     cacheName: 'api-cache',     plugins: [       new CacheableResponsePlugin({         headers: {           'X-Is-Cacheable': 'true'         }       })     ]   }) )<\/code><\/pre>\n<p>  <\/p>\n<p>\u041f\u0440\u0438 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0435 \u043e\u0442\u0432\u0435\u0442\u043e\u0432 \u043d\u0430 \u0437\u0430\u043f\u0440\u043e\u0441\u044b \u043a <code>URL<\/code>, \u043d\u0430\u0447\u0438\u043d\u0430\u044e\u0449\u0435\u043c\u0443\u0441\u044f \u0441 <code>\/path\/to\/api\/<\/code>, \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u0442\u0441\u044f, \u043f\u0440\u0438\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u0435\u0442 \u043b\u0438 \u0432 \u043e\u0442\u0432\u0435\u0442\u0435 \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043e\u043a <code>X-Is-Cacheable<\/code> (\u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0441\u0435\u0440\u0432\u0435\u0440\u043e\u043c). \u0415\u0441\u043b\u0438 \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043e\u043a \u043f\u0440\u0438\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u0435\u0442 \u0438 \u0438\u043c\u0435\u0435\u0442 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 <code>true<\/code>, \u0442\u0430\u043a\u043e\u0439 \u043e\u0442\u0432\u0435\u0442 \u043a\u044d\u0448\u0438\u0440\u0443\u0435\u0442\u0441\u044f.<\/p>\n<p>  <\/p>\n<p>\u041f\u0440\u0438 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0438 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043a\u043e\u0432, \u0434\u043b\u044f \u043a\u044d\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u043e\u0442\u0432\u0435\u0442\u0430 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0441\u043e\u0432\u043f\u0430\u0434\u0435\u043d\u0438\u044f \u0441 \u043e\u0434\u043d\u0438\u043c \u0438\u0437 \u043d\u0438\u0445.<\/p>\n<p>  <\/p>\n<p>\u0420\u0430\u0437\u0443\u043c\u0435\u0435\u0442\u0441\u044f, \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u044b\u0435 \u0442\u0435\u0445\u043d\u0438\u043a\u0438 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u044f \u043f\u0440\u0438\u0433\u043e\u0434\u043d\u043e\u0441\u0442\u0438 \u043e\u0442\u0432\u0435\u0442\u043e\u0432 \u0434\u043b\u044f \u043a\u044d\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u043c\u043e\u0436\u043d\u043e \u043a\u043e\u043c\u0431\u0438\u043d\u0438\u0440\u043e\u0432\u0430\u0442\u044c:<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">import { registerRoute } from 'workbox-routing' import { StaleWhileRevalidate } from 'workbox-strategies' import { CacheableResponsePlugin } from 'workbox-cacheable-response'  registerRoute(   ({ url }) =&gt; url.pathname.startsWith('\/path\/to\/api\/'),   new StaleWhileRevalidate({     cacheName: 'api-cache',     plugins: [       new CacheableResponsePlugin({         statuses: [200, 404],         headers: {           'X-Is-Cacheable': 'true'         }       })     ]   }) )<\/code><\/pre>\n<p>  <\/p>\n<p>\u041f\u0440\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0438 \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u043e\u0439 \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u0438 \u0431\u0435\u0437 \u044f\u0432\u043d\u043e\u0433\u043e \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u044f <code>cacheableResponse.CacheableResponsePlugin<\/code>, \u0434\u043b\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0432\u0430\u043b\u0438\u0434\u043d\u043e\u0441\u0442\u0438 \u043e\u0442\u0432\u0435\u0442\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442\u0441\u044f \u0441\u043b\u0435\u0434\u044e\u0449\u0438\u0435 \u043a\u0440\u0438\u0442\u0435\u0440\u0438\u0438:<\/p>\n<p>  <\/p>\n<ul>\n<li><code>staleWhileRevalidate<\/code> \u0438 <code>networkFirst<\/code>: \u043e\u0442\u0432\u0435\u0442\u044b \u0441\u043e \u0441\u0442\u0430\u0442\u0443\u0441\u043e\u043c <code>0<\/code> (\u043d\u0435\u043f\u0440\u043e\u0437\u0440\u0430\u0447\u043d\u044b\u0435 \u043e\u0442\u0432\u0435\u0442\u044b) \u0438 <code>200<\/code> \u0441\u0447\u0438\u0442\u0430\u044e\u0442\u0441\u044f \u0432\u0430\u043b\u0438\u0434\u043d\u044b\u043c\u0438<\/li>\n<li><code>cacheFirst<\/code>: \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u0442\u0432\u0435\u0442\u044b \u0441\u043e \u0441\u0442\u0430\u0442\u0443\u0441\u043e\u043c <code>200<\/code> \u0441\u0447\u0438\u0442\u0430\u044e\u0442\u0441\u044f \u0432\u0430\u043b\u0438\u0434\u043d\u044b\u043c\u0438<\/li>\n<\/ul>\n<p>  <\/p>\n<p>\u041f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043a\u0438 \u043e\u0442\u0432\u0435\u0442\u0430 \u0434\u043b\u044f \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u044f \u0435\u0433\u043e \u0432\u0430\u043b\u0438\u0434\u043d\u043e\u0441\u0442\u0438 \u043d\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442\u0441\u044f.<\/p>\n<p>  <\/p>\n<h3 id=\"prodvinutoe-ispolzovanie-1\">\u041f\u0440\u043e\u0434\u0432\u0438\u043d\u0443\u0442\u043e\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435<\/h3>\n<p>  <\/p>\n<p>\u0414\u043b\u044f \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u044f \u043b\u043e\u0433\u0438\u043a\u0438 \u043a\u044d\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0437\u0430 \u043f\u0440\u0435\u0434\u0435\u043b\u0430\u043c\u0438 \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u0438 \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043a\u043b\u0430\u0441\u0441 <code>CacheableResponse<\/code>:<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">import { CacheableResponse } from 'workbox-cacheable-response'  const cacheable = new CacheableResponse({   statuses: [0, 200],   headers: {     'X-Is-Cacheable': 'true'   } })  const response = await fetch('\/path\/to\/api')  if (cacheable.isResponseCacheable(response)) {   const cache = await caches.open('api-cache')   cache.put(response.url, response) } else {   \/\/ \u041e\u0442\u0432\u0435\u0442 \u043d\u0435 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043a\u044d\u0448\u0438\u0440\u043e\u0432\u0430\u043d }<\/code><\/pre>\n<p>  <\/p>\n<h2 id=\"workbox-expiration\"><code>workbox-expiration<\/code><\/h2>\n<p>  <\/p>\n<p>\u0414\u0430\u043d\u043d\u044b\u0439 \u043f\u043b\u0430\u0433\u0438\u043d \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0438\u0432\u0430\u0442\u044c \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432, \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u043c\u044b\u0445 \u0432 \u043a\u044d\u0448\u0435, \u0430 \u0442\u0430\u043a\u0436\u0435 \u0432\u0440\u0435\u043c\u044f \u0438\u0445 \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f.<\/p>\n<p>  <\/p>\n<h3 id=\"ogranichenie-kolichestva-zapisey-v-keshe\">\u041e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u0430 \u0437\u0430\u043f\u0438\u0441\u0435\u0439 \u0432 \u043a\u044d\u0448\u0435<\/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(   ({ request }) =&gt; request.destination === 'image',   new CacheFirst({     cacheName: 'image-cache',     plugins: [       new ExpirationPlugin({         \/\/ \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0438\u0432\u0430\u0435\u043c \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0437\u0430\u043f\u0438\u0441\u0435\u0439 \u0432 \u043a\u044d\u0448\u0435         maxEntries: 20       })     ]   }) )<\/code><\/pre>\n<p>  <\/p>\n<p>\u041f\u0440\u0438 \u0434\u043e\u0441\u0442\u0438\u0436\u0435\u043d\u0438\u0438 \u043b\u0438\u043c\u0438\u0442\u0430 \u0443\u0434\u0430\u043b\u044f\u044e\u0442\u0441\u044f \u0441\u0430\u043c\u044b\u0435 \u0441\u0442\u0430\u0440\u044b\u0435 \u0437\u0430\u043f\u0438\u0441\u0438.<\/p>\n<p>  <\/p>\n<h3 id=\"ogranichenie-vremeni-hraneniya-resursov-v-keshe\">\u041e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u0435 \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432 \u0432 \u043a\u044d\u0448\u0435<\/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(   ({ request }) =&gt; request.destination === 'image',   new CacheFirst({     cacheName: 'image-cache',     plugins: [       new ExpirationPlugin({         \/\/ \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0438\u0432\u0430\u0435\u043c \u0432\u0440\u0435\u043c\u044f \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432 \u0432 \u043a\u044d\u0448\u0435         maxAgeSeconds: 24 * 60 * 60       })     ]   }) )<\/code><\/pre>\n<p>  <\/p>\n<p>\u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u0437\u0430\u043f\u0438\u0441\u0435\u0439 \u043d\u0430 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0438\u0435 \u044d\u0442\u043e\u043c\u0443 \u043a\u0440\u0438\u0442\u0435\u0440\u0438\u044e \u0438, \u043f\u0440\u0438 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u0438, \u0438\u0445 \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u0435 \u043e\u0441\u0443\u0449\u0435\u0441\u0442\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043f\u043e\u0441\u043b\u0435 \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u0438\u043b\u0438 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f \u043a\u044d\u0448\u0430.<\/p>\n<p>  <\/p>\n<h3 id=\"prodvinutoe-ispolzovanie-2\">\u041f\u0440\u043e\u0434\u0432\u0438\u043d\u0443\u0442\u043e\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435<\/h3>\n<p>  <\/p>\n<p>\u041a\u043b\u0430\u0441\u0441 <code>CacheExpiration<\/code> \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043e\u0442\u0434\u0435\u043b\u044f\u0442\u044c \u043b\u043e\u0433\u0438\u043a\u0443 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u044f \u043e\u0442 \u0434\u0440\u0443\u0433\u0438\u0445 \u043c\u043e\u0434\u0443\u043b\u0435\u0439. \u0414\u043b\u044f \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u0439 \u0441\u043e\u0437\u0434\u0430\u0435\u0442\u0441\u044f \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440 \u043d\u0430\u0437\u0432\u0430\u043d\u043d\u043e\u0433\u043e \u043a\u043b\u0430\u0441\u0441\u0430:<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">import { CacheExpiration } from 'workbox-expiration'  const cacheName = 'my-cache' const expirationManager = new CacheExpiration(cacheName, {   maxAgeSeconds: 24 * 60 * 60,   maxEntries: 20 })<\/code><\/pre>\n<p>  <\/p>\n<p>\u0417\u0430\u0442\u0435\u043c, \u043f\u0440\u0438 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0438 \u0437\u0430\u043f\u0438\u0441\u0438 \u0432 \u043a\u044d\u0448\u0435, \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043c\u0435\u0442\u043e\u0434 <code>updateTimestamp()<\/code> \u0434\u043b\u044f \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f &quot;\u0432\u043e\u0437\u0440\u0430\u0441\u0442\u0430&quot; \u0437\u0430\u043f\u0438\u0441\u0438.<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">await openCache.put(request, response)  await expirationManager.updateTimestamp(request.url)<\/code><\/pre>\n<p>  <\/p>\n<p>\u0414\u043b\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0432\u0441\u0435\u0445 \u0437\u0430\u043f\u0438\u0441\u0435\u0439 \u0432 \u043a\u044d\u0448\u0435 \u043d\u0430 \u043f\u0440\u0435\u0434\u043c\u0435\u0442 \u0438\u0445 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0438\u044f \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u043d\u044b\u043c \u043a\u0440\u0438\u0442\u0435\u0440\u0438\u044f\u043c \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043c\u0435\u0442\u043e\u0434 <code>expireEntries()<\/code>:<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">await expirationManager.expireEntries()<\/code><\/pre>\n<p>  <\/p>\n<h2 id=\"workbox-precaching\"><code>workbox-precaching<\/code><\/h2>\n<p>  <\/p>\n<p>\u0421\u0412 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0442\u044c \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. \u042d\u0442\u043e \u043d\u0430\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043f\u0440\u0435\u0434\u0432\u0430\u0440\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u043c \u043a\u044d\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435\u043c, \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u043a\u043e\u043d\u0442\u0435\u043d\u0442 \u043a\u044d\u0448\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u043f\u0435\u0440\u0435\u0434 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u0421\u0412.<\/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 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044e \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0432 \u0440\u0435\u0436\u0438\u043c\u0435 \u043e\u0444\u043b\u0430\u0439\u043d \u0431\u0435\u0437 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0441\u0435\u0442\u0435\u0432\u044b\u0445 \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 \u043d\u0430 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u044b\u0445 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435\u043c.<\/p>\n<p>  <\/p>\n<p><code>WB<\/code> \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u0438 \u043f\u043e\u043d\u044f\u0442\u043d\u044b\u0439 <code>API<\/code> \u0434\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 \u0438 \u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u043e\u0439 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432.<\/p>\n<p>  <\/p>\n<p>\u041f\u0440\u0438 \u043f\u0435\u0440\u0432\u043e\u043c \u0437\u0430\u043f\u0443\u0441\u043a\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f <code>workbox-precaching<\/code> &quot;\u0441\u043c\u043e\u0442\u0440\u0438\u0442&quot; \u043d\u0430 \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0435\u043c\u044b\u0435 \u0440\u0435\u0441\u0443\u0440\u0441\u044b, \u0443\u0434\u0430\u043b\u044f\u0435\u0442 \u0434\u0443\u0431\u043b\u0438\u043a\u0430\u0442\u044b \u0438 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u0443\u0435\u0442 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0435 \u0441\u043e\u0431\u044b\u0442\u0438\u044f \u0421\u0412 \u0434\u043b\u044f \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u0438 \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432. <code>URL<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u043e \u0432\u0435\u0440\u0441\u0438\u0438 (\u0432\u0435\u0440\u0441\u0438\u043e\u043d\u043d\u0443\u044e \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e) (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0445\u044d\u0448 \u043a\u043e\u043d\u0442\u0435\u043d\u0442\u0430) \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442\u0441\u044f \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043a\u043b\u044e\u0447\u0435\u0439 \u043a\u044d\u0448\u0430 \u0431\u0435\u0437 \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0439 \u043c\u043e\u0434\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438. \u041a \u043a\u043b\u044e\u0447\u0430\u043c \u043a\u044d\u0448\u0430 <code>URL<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043d\u0435 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442 \u0442\u0430\u043a\u043e\u0439 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438, \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440 \u0441\u0442\u0440\u043e\u043a\u0438 \u0437\u0430\u043f\u0440\u043e\u0441\u0430, \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u044e\u0449\u0438\u0439 \u0445\u044d\u0448 \u043a\u043e\u043d\u0442\u0435\u043d\u0442\u0430, \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u043c\u044b\u0439 <code>WB<\/code> \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f.<\/p>\n<p>  <\/p>\n<p><code>workbox-precaching<\/code> \u0434\u0435\u043b\u0430\u0435\u0442 \u0432\u0441\u0435 \u044d\u0442\u043e \u043f\u0440\u0438 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0435 \u0441\u043e\u0431\u044b\u0442\u0438\u044f <code>install<\/code> \u0421\u0412.<\/p>\n<p>  <\/p>\n<p>\u041f\u0440\u0438 \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u043e\u043c \u043f\u043e\u0441\u0435\u0449\u0435\u043d\u0438\u0438 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u043c, \u043f\u0440\u0438 \u043d\u0430\u043b\u0438\u0447\u0438\u0438 \u043d\u043e\u0432\u043e\u0433\u043e \u0421\u0412 \u0441 \u0434\u0440\u0443\u0433\u0438\u043c\u0438 \u043f\u0440\u0435\u0434\u0432\u0430\u0440\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043a\u044d\u0448\u0438\u0440\u0443\u0435\u043c\u044b\u043c\u0438 \u0440\u0435\u0441\u0443\u0440\u0441\u0430\u043c\u0438 <code>workbox-precaching<\/code> \u043e\u0446\u0435\u043d\u0438\u0432\u0430\u0435\u0442 \u043d\u043e\u0432\u044b\u0439 \u0441\u043f\u0438\u0441\u043e\u043a \u0438 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442, \u043a\u0430\u043a\u0438\u0435 \u0440\u0435\u0441\u0443\u0440\u0441\u044b \u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u043d\u043e\u0432\u044b\u043c\u0438, \u0430 \u043a\u0430\u043a\u0438\u0435 \u043d\u0443\u0436\u0434\u0430\u044e\u0442\u0441\u044f \u0432 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0438 \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u0432\u0435\u0440\u0441\u0438\u043e\u043d\u043d\u043e\u0439 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438. \u0414\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043d\u043e\u0432\u044b\u0445 \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432 \u0438\u043b\u0438 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0445 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f \u043f\u0440\u0438 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0435 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0433\u043e \u0441\u043e\u0431\u044b\u0442\u0438\u044f <code>install<\/code>.<\/p>\n<p>  <\/p>\n<p>\u041d\u043e\u0432\u044b\u0439 \u0421\u0412 \u043d\u0435 \u0431\u0443\u0434\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0434\u043b\u044f \u043e\u0442\u0432\u0435\u0442\u043e\u0432 \u043d\u0430 \u0437\u0430\u043f\u0440\u043e\u0441\u044b \u0434\u043e \u0435\u0433\u043e \u0430\u043a\u0442\u0438\u0432\u0430\u0446\u0438\u0438. \u0412 \u0441\u043e\u0431\u044b\u0442\u0438\u0438 <code>activate<\/code> <code>workbox-precaching<\/code> \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442 \u043a\u044d\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u0440\u0435\u0441\u0443\u0440\u0441\u044b, \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0435 \u0432 \u043d\u043e\u0432\u043e\u043c \u0441\u043f\u0438\u0441\u043a\u0435 <code>URL<\/code>, \u0438 \u0443\u0434\u0430\u043b\u044f\u0435\u0442 \u0438\u0445 \u0438\u0437 \u043a\u044d\u0448\u0430.<\/p>\n<p>  <\/p>\n<h3 id=\"obrabotka-predvaritelno-keshirovannyh-otvetov\">\u041e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \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 \u043e\u0442\u0432\u0435\u0442\u043e\u0432<\/h3>\n<p>  <\/p>\n<p>\u0412\u044b\u0437\u043e\u0432 <code>precacheAndRoute()<\/code> \u0438\u043b\u0438 <code>addRoute()<\/code> \u0441\u043e\u0437\u0434\u0430\u0435\u0442 \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0438\u0437\u0430\u0442\u043e\u0440, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442 \u0441\u043e\u0432\u043f\u0430\u0434\u0435\u043d\u0438\u044f \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 \u0441 \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\u043c\u0438 <code>URL<\/code>.<\/p>\n<p>  <\/p>\n<p>\u0412 \u044d\u0442\u043e\u043c \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0438\u0437\u0430\u0442\u043e\u0440\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u044f &quot;\u0441\u043d\u0430\u0447\u0430\u043b\u0430 \u043a\u044d\u0448&quot;.<\/p>\n<p>  <\/p>\n<p>\u041f\u043e\u0440\u044f\u0434\u043e\u043a \u0432\u044b\u0437\u043e\u0432\u0430 \u043d\u0430\u0437\u0432\u0430\u043d\u043d\u044b\u0445 \u043c\u0435\u0442\u043e\u0434\u043e\u0432 \u0438\u043c\u0435\u0435\u0442 \u0432\u0430\u0436\u043d\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435. \u041e\u0431\u044b\u0447\u043d\u043e, \u043e\u043d\u0438 \u0432\u044b\u0437\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u0432 \u043d\u0430\u0447\u0430\u043b\u0435 \u0444\u0430\u0439\u043b\u0430 \u0441 \u043a\u043e\u0434\u043e\u043c \u0421\u0412, \u043f\u0435\u0440\u0435\u0434 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u0435\u0439 \u0438 \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u043c\u0438 \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0438\u0437\u0430\u0442\u043e\u0440\u0430\u043c\u0438, \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u043c\u044b\u043c\u0438 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e <code>registerRoute()<\/code>. \u0415\u0441\u043b\u0438 \u0432\u044b\u0437\u0432\u0430\u0442\u044c \u0441\u043d\u0430\u0447\u0430\u043b\u0430 <code>registerRoute()<\/code>, \u0442\u043e \u043b\u044e\u0431\u043e\u0439 \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0438\u0437\u0430\u0442\u043e\u0440, \u0441\u043e\u0432\u043f\u0430\u0432\u0448\u0438\u0439 \u0441 \u0432\u0445\u043e\u0434\u044f\u0449\u0438\u043c \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u043c, \u043d\u0435\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e \u043e\u0442 \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u0438, \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u043e\u0439 \u0432 \u044d\u0442\u043e\u043c \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0438\u0437\u0430\u0442\u043e\u0440\u0435, \u0431\u0443\u0434\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d \u0434\u043b\u044f \u0444\u043e\u0440\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u043e\u0442\u0432\u0435\u0442\u0430.<\/p>\n<p>  <\/p>\n<h3 id=\"spisok-predvaritelno-keshiruemyh-resursov\">\u0421\u043f\u0438\u0441\u043e\u043a \u043f\u0440\u0435\u0434\u0432\u0430\u0440\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043a\u044d\u0448\u0438\u0440\u0443\u0435\u043c\u044b\u0445 \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432<\/h3>\n<p>  <\/p>\n<p><code>workbox-precaching<\/code> \u043e\u0436\u0438\u0434\u0430\u0435\u0442 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u043c\u0430\u0441\u0441\u0438\u0432\u0430 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432 \u0441\u043e \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430\u043c\u0438 <code>url<\/code> \u0438 <code>revision<\/code>. \u0414\u0430\u043d\u043d\u044b\u0439 \u043c\u0430\u0441\u0441\u0438\u0432 \u0438\u043d\u043e\u0433\u0434\u0430 \u043d\u0430\u0437\u044b\u0432\u0430\u044e\u0442 &quot;\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&quot;:<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">import { precacheAndRoute } from 'workbox-precaching'  precacheAndRoute([   { url: '\/index.html', revision: '383676' },   { url: '\/styles\/app.0c9a31.css', revision: null },   { url: '\/scripts\/app.0d5770.js', revision: null },   \/\/ \u0434\u0440\u0443\u0433\u0438\u0435 \u0437\u0430\u043f\u0438\u0441\u0438 ])<\/code><\/pre>\n<p>  <\/p>\n<p>\u0421\u0432\u043e\u0439\u0441\u0442\u0432\u0430 <code>revision<\/code> \u0432\u0442\u043e\u0440\u043e\u0433\u043e \u0438 \u0442\u0440\u0435\u0442\u044c\u0435\u0433\u043e \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432 \u0438\u043c\u0435\u044e\u0442 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f <code>null<\/code>. \u042d\u0442\u043e \u043e\u0431\u044a\u044f\u0441\u043d\u044f\u0435\u0442\u0441\u044f \u0442\u0435\u043c, \u0447\u0442\u043e \u0432\u0435\u0440\u0441\u0438\u043e\u043d\u043d\u0430\u044f \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f \u044d\u0442\u0438\u0445 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0447\u0430\u0441\u0442\u044c\u044e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439 \u0438\u0445 \u0441\u0432\u043e\u0439\u0441\u0442\u0432 <code>url<\/code>.<\/p>\n<p>  <\/p>\n<p>\u0412 \u043e\u0442\u043b\u0438\u0447\u0438\u0435 \u043e\u0442 <code>JavaScript<\/code> \u0438 <code>CSS<\/code> <code>URL<\/code>, \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u044e\u0449\u0438\u0435 \u043d\u0430 <code>HTML-\u0444\u0430\u0439\u043b\u044b<\/code>, \u043a\u0430\u043a \u043f\u0440\u0430\u0432\u0438\u043b\u043e, \u043d\u0435 \u0432\u043a\u043b\u044e\u0447\u0430\u044e\u0442 \u0432 \u0441\u0435\u0431\u044f \u0432\u0435\u0440\u0441\u0438\u043e\u043d\u043d\u0443\u044e \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u043f\u043e \u0442\u043e\u0439 \u043f\u0440\u0438\u0447\u0438\u043d\u0435, \u0447\u0442\u043e \u0441\u0441\u044b\u043b\u043a\u0438 \u043d\u0430 \u0442\u0430\u043a\u0438\u0435 \u0444\u0430\u0439\u043b\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u0431\u044b\u0442\u044c \u0441\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u043c\u0438.<\/p>\n<p>  <\/p>\n<p>\u0412\u0435\u0440\u0441\u0438\u043e\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0440\u0430\u0441\u0441\u043c\u0430\u0442\u0440\u0438\u0432\u0430\u0435\u043c\u043e\u043c\u0443 \u043c\u043e\u0434\u0443\u043b\u044e \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0442\u044c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u044c \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f \u043a\u044d\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0433\u043e \u0440\u0435\u0441\u0443\u0440\u0441\u0430.<\/p>\n<p>  <\/p>\n<p><em>\u041e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435<\/em>: \u0434\u043b\u044f \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u0441\u043f\u0438\u0441\u043a\u0430 \u043f\u0440\u0435\u0434\u0432\u0430\u0440\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043a\u044d\u0448\u0438\u0440\u0443\u0435\u043c\u044b\u0445 \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432 \u0441\u043b\u0435\u0434\u0443\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \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>: <code>workbox-build<\/code>, <code>workbox-webpack-plugin<\/code> \u0438\u043b\u0438 <code>workbox-cli<\/code>. \u0421\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u0442\u0430\u043a\u043e\u0439 \u0441\u043f\u0438\u0441\u043e\u043a \u0432\u0440\u0443\u0447\u043d\u0443\u044e \u2014 \u043e\u0447\u0435\u043d\u044c \u043f\u043b\u043e\u0445\u0430\u044f \u0438\u0434\u0435\u044f.<\/p>\n<p>  <\/p>\n<h3 id=\"avtomaticheskaya-obrabotka-vhodyaschih-zaprosov\">\u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0430\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u0432\u0445\u043e\u0434\u044f\u0449\u0438\u0445 \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432<\/h3>\n<p>  <\/p>\n<p>\u041f\u0440\u0438 \u043f\u043e\u0438\u0441\u043a\u0435 \u0441\u043e\u0432\u043f\u0430\u0434\u0435\u043d\u0438\u044f \u0432\u0445\u043e\u0434\u044f\u0449\u0435\u0433\u043e \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u0441 \u043a\u044d\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u043c \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u043c <code>workbox-precaching<\/code> \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u0430\u043d\u0438\u043f\u0443\u043b\u044f\u0446\u0438\u0438 \u0441 <code>URL<\/code>.<\/p>\n<p>  <\/p>\n<p>\u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0437\u0430\u043f\u0440\u043e\u0441 \u043a <code>\/<\/code> \u043e\u0446\u0435\u043d\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u043a\u0430\u043a \u0437\u0430\u043f\u0440\u043e\u0441 \u043a <code>index.html<\/code>.<\/p>\n<p>  <\/p>\n<p><strong>\u0418\u0433\u043d\u043e\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432 \u0441\u0442\u0440\u043e\u043a\u0438 \u0437\u0430\u043f\u0440\u043e\u0441\u0430<\/strong><\/p>\n<p>  <\/p>\n<p>\u041f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e \u0438\u0433\u043d\u043e\u0440\u0438\u0440\u0443\u044e\u0442\u0441\u044f \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u043f\u043e\u0438\u0441\u043a\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043d\u0430\u0447\u0438\u043d\u0430\u044e\u0442\u0441\u044f \u0441 <code>utm_<\/code> \u0438\u043b\u0438 \u0442\u043e\u0447\u043d\u043e \u0441\u043e\u0432\u043f\u0430\u0434\u0430\u044e\u0442 \u0441 <code>fbclid<\/code>. \u042d\u0442\u043e \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442, \u0447\u0442\u043e \u0437\u0430\u043f\u0440\u043e\u0441 \u043a <code>\/about.html?utm_campaign=abcd<\/code> \u043e\u0446\u0435\u043d\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u043a\u0430\u043a \u0437\u0430\u043f\u0440\u043e\u0441 \u043a <code>\/about.html<\/code>.<\/p>\n<p>  <\/p>\n<p>\u0418\u0433\u043d\u043e\u0440\u0438\u0440\u0443\u0435\u043c\u044b\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u0432 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0435 <code>ignoreURLParametersMatching<\/code>:<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">import { precacheAndRoute } from 'workbox-precaching'  precacheAndRoute(   [     { url: '\/index.html', revision: '383676' },     { url: '\/styles\/app.0c9a31.css', revision: null },     { url: '\/scripts\/app.0d5770.js', revision: null }   ],   {     \/\/ \u0418\u0433\u043d\u043e\u0440\u0438\u0440\u0443\u0435\u043c \u0432\u0441\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b     ignoreURLParametersMatching: [\/.*\/]   } )<\/code><\/pre>\n<p>  <\/p>\n<p><strong>\u041e\u0441\u043d\u043e\u0432\u043d\u043e\u0439 \u0444\u0430\u0439\u043b \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u0438<\/strong><\/p>\n<p>  <\/p>\n<p>\u041f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u043c \u0444\u0430\u0439\u043b\u043e\u043c \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u0438 \u0441\u0447\u0438\u0442\u0430\u0435\u0442\u0441\u044f <code>index.html<\/code>. \u0418\u043c\u0435\u043d\u043d\u043e \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0437\u0430\u043f\u0440\u043e\u0441\u044b \u043a <code>\/<\/code> \u043e\u0446\u0435\u043d\u0438\u0432\u0430\u044e\u0442\u0441\u044f \u043a\u0430\u043a \u0437\u0430\u043f\u0440\u043e\u0441\u044b \u043a <code>\/index.html<\/code>. \u042d\u0442\u043e \u043f\u043e\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \u043c\u043e\u0436\u043d\u043e \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u044c \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 <code>directoryIndex<\/code>:<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">import { precacheAndRoute } from 'workbox-precaching'  precacheAndRoute(   [     { url: '\/index.html', revision: '383676' },     { url: '\/styles\/app.0c9a31.css', revision: null },     { url: '\/scripts\/app.0d5770.js', revision: null },   ],   {     directoryIndex: null   } )<\/code><\/pre>\n<p>  <\/p>\n<p><strong>&quot;\u0427\u0438\u0441\u0442\u044b\u0435&quot; URL<\/strong><\/p>\n<p>  <\/p>\n<p>\u041f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e \u043a \u0437\u0430\u043f\u0440\u043e\u0441\u0443 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u0435 <code>.html<\/code>. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0437\u0430\u043f\u0440\u043e\u0441 \u043a <code>\/about<\/code> \u043e\u0446\u0435\u043d\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u043a\u0430\u043a <code>\/about.html<\/code>. \u042d\u0442\u043e \u043c\u043e\u0436\u043d\u043e \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u044c \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 <code>cleanUrls<\/code>:<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">import { precacheAndRoute } from 'workbox-precaching'  precacheAndRoute([{ url: '\/about.html', revision: 'b79cd4' }], {   cleanUrls: false })<\/code><\/pre>\n<p>  <\/p>\n<p><strong>\u041a\u0430\u0441\u0442\u043e\u043c\u043d\u044b\u0435 \u043c\u0430\u043d\u0438\u043f\u0443\u043b\u044f\u0446\u0438\u0438<\/strong><\/p>\n<p>  <\/p>\n<p>\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 <code>urlManipulation<\/code> \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043a\u0430\u0441\u0442\u043e\u043c\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043b\u043e\u0433\u0438\u043a\u0443 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u044f \u0441\u043e\u0432\u043f\u0430\u0434\u0435\u043d\u0438\u0439. \u042d\u0442\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0434\u043e\u043b\u0436\u043d\u0430 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0442\u044c \u043c\u0430\u0441\u0441\u0438\u0432 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u044b\u0445 \u0441\u043e\u0432\u043f\u0430\u0434\u0435\u043d\u0438\u0439:<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">import { precacheAndRoute } from 'workbox-precaching'  precacheAndRoute(   [     { url: '\/index.html', revision: '383676' },     { url: '\/styles\/app.0c9a31.css', revision: null },     { url: '\/scripts\/app.0d5770.js', revision: null }   ],   {     urlManipulation: ({ url }) =&gt; {       \/\/ \u041b\u043e\u0433\u0438\u043a\u0430 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u044f \u0441\u043e\u0432\u043f\u0430\u0434\u0435\u043d\u0438\u0439       return [alteredUrlOption1, alteredUrlOption2]     }   } )<\/code><\/pre>\n<p>  <\/p>\n<h2 id=\"workbox-routing\"><code>workbox-routing<\/code><\/h2>\n<p>  <\/p>\n<p>\u0421\u0412 \u043c\u043e\u0436\u0435\u0442 \u043f\u0435\u0440\u0435\u0445\u0432\u0430\u0442\u044b\u0432\u0430\u0442\u044c \u0441\u0435\u0442\u0435\u0432\u044b\u0435 \u0437\u0430\u043f\u0440\u043e\u0441\u044b. \u041e\u043d \u043c\u043e\u0436\u0435\u0442 \u043e\u0442\u0432\u0435\u0447\u0430\u0442\u044c \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0443 \u043a\u044d\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u043c \u043a\u043e\u043d\u0442\u0435\u043d\u0442\u043e\u043c, \u043a\u043e\u043d\u0442\u0435\u043d\u0442\u043e\u043c, \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u043c \u0438\u0437 \u0441\u0435\u0442\u0438, \u0438\u043b\u0438 \u043a\u043e\u043d\u0442\u0435\u043d\u0442\u043e\u043c, \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u043c\u044b\u043c \u0421\u0412.<\/p>\n<p>  <\/p>\n<p><code>workbox-routing<\/code> \u2014 \u044d\u0442\u043e \u043c\u043e\u0434\u0443\u043b\u044c, \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0449\u0438\u0439 &quot;\u0441\u0432\u044f\u0437\u044b\u0432\u0430\u0442\u044c&quot; \u043f\u043e\u0441\u0442\u0443\u043f\u0430\u044e\u0449\u0438\u0435 \u0437\u0430\u043f\u0440\u043e\u0441\u044b \u0441 \u0444\u0443\u043d\u043a\u0446\u0438\u044f\u043c\u0438, \u0444\u043e\u0440\u043c\u0438\u0440\u0443\u044e\u0449\u0438\u043c\u0438 \u043d\u0430 \u043d\u0438\u0445 \u043e\u0442\u0432\u0435\u0442\u044b.<\/p>\n<p>  <\/p>\n<p>\u041f\u0440\u0438 \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0435 \u0441\u0435\u0442\u0435\u0432\u043e\u0433\u043e \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u0432\u043e\u0437\u043d\u0438\u043a\u0430\u0435\u0442 \u0441\u043e\u0431\u044b\u0442\u0438\u0435 <code>fetch<\/code>, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u0443\u0435\u0442 \u0421\u0412 \u0434\u043b\u044f \u0444\u043e\u0440\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u043e\u0442\u0432\u0435\u0442\u0430 \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0438\u0437\u0430\u0442\u043e\u0440\u043e\u0432 \u0438 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u043e\u0432.<\/p>\n<p>  <\/p>\n<p><em>\u041e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435<\/em> \u043d\u0430 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0435:<\/p>\n<p>  <\/p>\n<ul>\n<li>\u0432\u0430\u0436\u043d\u043e \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u043c\u0435\u0442\u043e\u0434 \u0437\u0430\u043f\u0440\u043e\u0441\u0430. \u041f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e \u043f\u0435\u0440\u0435\u0445\u0432\u0430\u0442\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u0442\u043e\u043b\u044c\u043a\u043e <code>GET-\u0437\u0430\u043f\u0440\u043e\u0441\u044b<\/code><\/li>\n<li>\u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0438\u0437\u0430\u0442\u043e\u0440\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0432 \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e\u043c \u043f\u043e\u0440\u044f\u0434\u043a\u0435. \u041f\u0440\u0438 \u043d\u0430\u043b\u0438\u0447\u0438\u0438 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 &quot;\u0440\u043e\u0443\u0442\u043e\u0432&quot; \u0434\u043b\u044f \u043e\u0434\u043d\u043e\u0433\u043e \u0437\u0430\u043f\u0440\u043e\u0441\u0430, \u0441\u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u0435\u0440\u0432\u044b\u0439 \u0438\u0437 \u043d\u0438\u0445<\/li>\n<\/ul>\n<p>  <\/p>\n<h3 id=\"opredelenie-sovpadeniy-i-obrabotka-zaprosov\">\u041e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u0441\u043e\u0432\u043f\u0430\u0434\u0435\u043d\u0438\u0439 \u0438 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432<\/h3>\n<p>  <\/p>\n<p>\u0412 <code>WB<\/code> &quot;\u0440\u043e\u0443\u0442&quot; \u2014 \u044d\u0442\u043e \u0434\u0432\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438: \u0444\u0443\u043d\u043a\u0446\u0438\u044f &quot;\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u044f \u0441\u043e\u0432\u043f\u0430\u0434\u0435\u043d\u0438\u044f&quot; \u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u044f &quot;\u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0437\u0430\u043f\u0440\u043e\u0441\u0430&quot;.<\/p>\n<p>  <\/p>\n<p><code>WB<\/code> \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0443\u0442\u0438\u043b\u0438\u0442\u044b \u0434\u043b\u044f \u043f\u043e\u043c\u043e\u0449\u0438 \u0432 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043d\u0430\u0437\u0432\u0430\u043d\u043d\u044b\u0445 \u0444\u0443\u043d\u043a\u0446\u0438\u0439.<\/p>\n<p>  <\/p>\n<p>\u0424\u0443\u043d\u043a\u0446\u0438\u044f \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u044f \u0441\u043e\u0432\u043f\u0430\u0434\u0435\u043d\u0438\u044f \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 <code>ExtendableEvent<\/code>, <code>Request<\/code> \u0438 \u043e\u0431\u044a\u0435\u043a\u0442 <code>URL<\/code>. \u0412\u043e\u0437\u0432\u0440\u0430\u0442 \u0438\u0441\u0442\u0438\u043d\u043d\u043e\u0433\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0438\u0437 \u044d\u0442\u043e\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442 \u0441\u043e\u0432\u043f\u0430\u0434\u0435\u043d\u0438\u0435. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0432\u043e\u0442 \u043f\u0440\u0438\u043c\u0435\u0440 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u044f \u0441\u043e\u0432\u043f\u0430\u0434\u0435\u043d\u0438\u044f \u0441 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u044b\u043c <code>URL<\/code>:<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">const matchCb = ({ url, request, event }) =&gt; {   return (url.pathname === '\/special\/url') }<\/code><\/pre>\n<p>  <\/p>\n<p>\u0424\u0443\u043d\u043a\u0446\u0438\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u0442\u0430\u043a\u0438\u0435 \u0436\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b + \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442 <code>value<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0438\u043c\u0435\u0435\u0442 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435, \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c\u043e\u0435 \u0438\u0437 \u043f\u0435\u0440\u0432\u043e\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0438:<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">const handlerCb = async ({ url, request, event, params }) =&gt; {   const response = await fetch(request)   const responseBody = await response.text()   return new Response(`${responseBody} &lt;!-- \u0413\u043b\u044f\u0434\u0438\u0442\u0435-\u043a\u0430! \u041d\u043e\u0432\u044b\u0439 \u043a\u043e\u043d\u0442\u0435\u043d\u0442. --&gt;`, {     headers: response.headers   }) }<\/code><\/pre>\n<p>  <\/p>\n<p>\u041e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u0434\u043e\u043b\u0436\u0435\u043d \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0442\u044c \u043f\u0440\u043e\u043c\u0438\u0441, \u0440\u0430\u0437\u0440\u0435\u0448\u0430\u044e\u0449\u0438\u0439\u0441\u044f <code>Response<\/code>.<\/p>\n<p>  <\/p>\n<p>\u0420\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u044f \u043a\u043e\u043b\u0431\u044d\u043a\u043e\u0432 \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c:<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">import { registerRoute } from 'workbox-routing'  registerRoute(matchCb, handlerCb)<\/code><\/pre>\n<p>  <\/p>\n<p>\u0415\u0434\u0438\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u043c \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u0435\u043c \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0442\u043e, \u0447\u0442\u043e \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u044f \u0441\u043e\u0432\u043f\u0430\u0434\u0435\u043d\u0438\u044f \u0434\u043e\u043b\u0436\u043d\u0430 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0442\u044c \u0438\u0441\u0442\u0438\u043d\u043d\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u043e. \u042d\u0442\u043e \u0441\u0432\u044f\u0437\u0430\u043d\u043e \u0441 \u0442\u0435\u043c, \u0447\u0442\u043e <code>Router<\/code> \u0434\u043e\u043b\u0436\u0435\u043d \u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u043e \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c \u0441\u043e\u0431\u044b\u0442\u0438\u0435 <code>fetch<\/code> \u0438\u043b\u0438 \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0442\u044c \u0435\u0433\u043e \u0434\u0440\u0443\u0433\u0438\u043c \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0430\u043c.<\/p>\n<p>  <\/p>\n<p>\u041a\u0430\u043a \u043f\u0440\u0430\u0432\u0438\u043b\u043e, \u0432 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u043e\u0434\u043d\u0430 \u0438\u0437 \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u044b\u0445 \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u0439, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440:<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">import { registerRoute } from 'workbox-routing' import { StaleWhileRevalidate } from 'workbox-strategies'  registerRoute(   matchCb,   new StaleWhileRevalidate() )<\/code><\/pre>\n<p>  <\/p>\n<h3 id=\"opredelenie-sovpadeniy-s-pomoschyu-regulyarnogo-vyrazheniya\">\u041e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u0441\u043e\u0432\u043f\u0430\u0434\u0435\u043d\u0438\u0439 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0440\u0435\u0433\u0443\u043b\u044f\u0440\u043d\u043e\u0433\u043e \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f<\/h3>\n<p>  <\/p>\n<p>\u0412\u043c\u0435\u0441\u0442\u043e \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u044f \u0441\u043e\u0432\u043f\u0430\u0434\u0435\u043d\u0438\u044f, \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0440\u0435\u0433\u0443\u043b\u044f\u0440\u043d\u043e\u0435 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435:<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">import { registerRoute } from 'workbox-routing'  registerRoute(   new RegExp('\/styles\/.*\\\\.css'),   handlerCb )<\/code><\/pre>\n<p>  <\/p>\n<p>\u0414\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 \u0434\u0430\u043d\u043d\u0430\u044f &quot;\u0440\u0435\u0433\u0443\u043b\u044f\u0440\u043a\u0430&quot; \u0431\u0443\u0434\u0435\u0442 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0441\u043e\u0432\u043f\u0430\u0434\u0435\u043d\u0438\u044f \u0434\u043b\u044f \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0445 <code>URL<\/code>:<\/p>\n<p>  <\/p>\n<ul>\n<li><a href=\"https:\/\/example.com\/styles\/main.css\">https:\/\/example.com\/styles\/main.css<\/a><\/li>\n<li><a href=\"https:\/\/example.com\/styles\/nested\/file.css\">https:\/\/example.com\/styles\/nested\/file.css<\/a><\/li>\n<li><a href=\"https:\/\/example.com\/nested\/styles\/directory.css\">https:\/\/example.com\/nested\/styles\/directory.css<\/a><\/li>\n<\/ul>\n<p>  <\/p>\n<p>\u041e\u0434\u043d\u0430\u043a\u043e, \u0432 \u0441\u043b\u0443\u0447\u0430\u0435 \u0441 \u0437\u0430\u043f\u0440\u043e\u0441\u0430\u043c\u0438 \u043a \u0434\u0440\u0443\u0433\u0438\u043c \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u0430\u043c, \u0440\u0435\u0433\u0443\u043b\u044f\u0440\u043a\u0430 <em>\u0434\u043e\u043b\u0436\u043d\u0430 \u0441\u043e\u0432\u043f\u0430\u0434\u0430\u0442\u044c \u0441 \u043d\u0430\u0447\u0430\u043b\u043e\u043c <code>URL<\/code><\/em>. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u0441\u043e\u0432\u043f\u0430\u0434\u0435\u043d\u0438\u0435 \u0434\u043b\u044f \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0445 <code>URL<\/code> \u043e\u0431\u043d\u0430\u0440\u0443\u0436\u0435\u043d\u043e \u043d\u0435 \u0431\u0443\u0434\u0435\u0442:<\/p>\n<p>  <\/p>\n<ul>\n<li><a href=\"https:\/\/cdn.third-party-site.com\/styles\/main.css\">https:\/\/cdn.third-party-site.com\/styles\/main.css<\/a><\/li>\n<li><a href=\"https:\/\/cdn.third-party-site.com\/styles\/nested\/file.css\">https:\/\/cdn.third-party-site.com\/styles\/nested\/file.css<\/a><\/li>\n<li><a href=\"https:\/\/cdn.third-party-site.com\/nested\/styles\/directory.css\">https:\/\/cdn.third-party-site.com\/nested\/styles\/directory.css<\/a><\/li>\n<\/ul>\n<p>  <\/p>\n<p>\u0414\u043b\u044f \u0440\u0435\u0448\u0435\u043d\u0438\u044f \u044d\u0442\u043e\u0439 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0442\u0430\u043a\u043e\u0435 \u0440\u0435\u0433\u0443\u043b\u044f\u0440\u043d\u043e\u0435 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435:<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">new RegExp('https:\/\/cdn\\\\.third-party-site\\\\.com.*\/styles\/.*\\\\.css')<\/code><\/pre>\n<p>  <\/p>\n<p>\u0414\u043b\u044f \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u0438 \u0441\u043e\u0432\u043f\u0430\u0434\u0435\u043d\u0438\u0439 \u043a\u0430\u043a \u0441 \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u044b\u043c\u0438, \u0442\u0430\u043a \u0438 \u0441\u043e \u0441\u0442\u043e\u0440\u043e\u043d\u043d\u0438\u043c\u0438 <code>URL<\/code> \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c <code>wildcard<\/code>, \u043d\u043e \u043f\u0440\u0438 \u044d\u0442\u043e\u043c \u0441\u043b\u0435\u0434\u0443\u0435\u0442 \u043f\u0440\u043e\u044f\u0432\u043b\u044f\u0442\u044c \u043e\u0441\u043e\u0431\u0443\u044e \u043e\u0441\u0442\u043e\u0440\u043e\u0436\u043d\u043e\u0441\u0442\u044c.<\/p>\n<p>  <\/p>\n<h3 id=\"rout-dlya-navigacii\">\u0420\u043e\u0443\u0442 \u0434\u043b\u044f \u043d\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u0438<\/h3>\n<p>  <\/p>\n<p>\u0415\u0441\u043b\u0438 \u0432\u0430\u0448\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u2014 \u044d\u0442\u043e \u043e\u0434\u043d\u043e\u0441\u0442\u0440\u0430\u043d\u0438\u0447\u043d\u0438\u043a, \u0434\u043b\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0432\u0441\u0435\u0445 \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432, \u0441\u0432\u044f\u0437\u0430\u043d\u043d\u044b\u0445 \u0441 \u043d\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u0435\u0439, \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c <code>NavigationRoute<\/code>.<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">import { createHandlerBoundToURL } from 'workbox-precaching' import { NavigationRoute, registerRoute } from 'workbox-routing'  \/\/ \u041f\u0440\u0435\u0434\u043f\u043e\u043b\u043e\u0436\u0438\u043c, \u0447\u0442\u043e \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430 `\/app-shell.html` \u0431\u044b\u043b\u0430 \u043f\u0440\u0435\u0434\u0432\u0430\u0440\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043a\u044d\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0430 const handler = createHandlerBoundToURL('\/app-shell.html') const navigationRoute = new NavigationRoute(handler) registerRoute(navigationRoute)<\/code><\/pre>\n<p>  <\/p>\n<p>\u041f\u0440\u0438 \u043f\u043e\u0441\u0435\u0449\u0435\u043d\u0438\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u043c \u0432\u0430\u0448\u0435\u0433\u043e \u0441\u0430\u0439\u0442\u0430, \u0437\u0430\u043f\u0440\u043e\u0441 \u043d\u0430 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b \u0431\u0443\u0434\u0435\u0442 \u0441\u0447\u0438\u0442\u0430\u0442\u044c\u0441\u044f \u043d\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u043c, \u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e, \u043e\u0442\u0432\u0435\u0442\u043e\u043c \u043d\u0430 \u043d\u0435\u0433\u043e \u0431\u0443\u0434\u0435\u0442 \u043a\u044d\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u0430\u044f \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430 <code>\/app-shell.html<\/code>.<\/p>\n<p>  <\/p>\n<p>\u041f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e \u0442\u0430\u043a\u043e\u0439 \u043e\u0442\u0432\u0435\u0442 \u0431\u0443\u0434\u0435\u0442 \u0444\u043e\u0440\u043c\u0438\u0440\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0434\u043b\u044f \u0432\u0441\u0435\u0445 \u043d\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u0445 \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432. \u042d\u0442\u043e \u043f\u043e\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \u043c\u043e\u0436\u043d\u043e \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u044c \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043a <code>allowList<\/code> \u0438 <code>denyList<\/code>, \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u0432 \u043d\u0430\u0431\u043e\u0440 <code>URL<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0434\u043e\u043b\u0436\u043d\u044b \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c\u0441\u044f \u044d\u0442\u0438\u043c \u0440\u043e\u0443\u0442\u043e\u043c.<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">import { createHandlerBoundToURL } from 'workbox-precaching' import { NavigationRoute, registerRoute } from 'workbox-routing'  const handler = createHandlerBoundToURL('\/app-shell.html')  const navigationRoute = new NavigationRoute(handler, {   allowlist: [     new RegExp('\/blog\/')   ],   denylist: [     new RegExp('\/blog\/restricted\/')   ] })  registerRoute(navigationRoute)<\/code><\/pre>\n<p>  <\/p>\n<p><strong>\u041e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435<\/strong>, \u0447\u0442\u043e <code>denyList<\/code> \u0438\u043c\u0435\u0435\u0442 \u043f\u0440\u0438\u043e\u0440\u0438\u0442\u0435\u0442 \u043f\u0435\u0440\u0435\u0434 <code>allowList<\/code>.<\/p>\n<p>  <\/p>\n<h3 id=\"obrabotchik-po-umolchaniyu\">\u041e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e<\/h3>\n<p>  <\/p>\n<pre><code class=\"plaintext\">import { setDefaultHandler } from 'workbox-routing'  setDefaultHandler(({ url, event, params }) =&gt; {   \/\/ ... })<\/code><\/pre>\n<p>  <\/p>\n<h3 id=\"obrabotchik-oshibok\">\u041e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u043e\u0448\u0438\u0431\u043e\u043a<\/h3>\n<p>  <\/p>\n<pre><code class=\"plaintext\">import { setCatchHandler } from 'workbox-routing'  setCatchHandler(({ url, event, params }) =&gt; {   \/\/ ... })<\/code><\/pre>\n<p>  <\/p>\n<h3 id=\"obrabotka-ne-get-zaprosov\">\u041e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 <code>\u043d\u0435-GET-\u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432<\/code><\/h3>\n<p>  <\/p>\n<pre><code class=\"plaintext\">import { registerRoute } from 'workbox-routing'  registerRoute(   matchCb,   handlerCb,   \/\/ \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u043c \u043c\u0435\u0442\u043e\u0434   'POST' )  registerRoute(   new RegExp('\/api\/.*\\\\.json'),   handlerCb,   \/\/ \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u043c \u043c\u0435\u0442\u043e\u0434   'POST' )<\/code><\/pre>\n<p>  <\/p>\n<h2 id=\"workbox-strategies\"><code>workbox-strategies<\/code><\/h2>\n<p>  <\/p>\n<p>\u0421\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u044f \u043a\u044d\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u2014 \u044d\u0442\u043e \u043f\u0430\u0442\u0442\u0435\u0440\u043d, \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u044e\u0449\u0438\u0439 \u043f\u043e\u0440\u044f\u0434\u043e\u043a \u0444\u043e\u0440\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0421\u0412 \u043e\u0442\u0432\u0435\u0442\u0430 \u043d\u0430 \u0437\u0430\u043f\u0440\u043e\u0441 (\u043f\u043e\u0441\u043b\u0435 \u0432\u043e\u0437\u043d\u0438\u043a\u043d\u043e\u0432\u0435\u043d\u0438\u044f \u0441\u043e\u0431\u044b\u0442\u0438\u044f <code>fetch<\/code>).<\/p>\n<p>  <\/p>\n<p>\u0412\u043e\u0442 \u043a\u0430\u043a\u0438\u0435 \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u0438 \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0440\u0430\u0441\u0441\u043c\u0430\u0442\u0440\u0438\u0432\u0430\u0435\u043c\u044b\u0439 \u043c\u043e\u0434\u0443\u043b\u044c.<\/p>\n<p>  <\/p>\n<h4 id=\"stale-while-revalidate\">Stale-While-Revalidate<\/h4>\n<p>  <\/p>\n<p>\u0414\u0430\u043d\u043d\u0430\u044f \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u044f \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u043e\u0442\u0432\u0435\u0442 \u0438\u0437 \u043a\u044d\u0448\u0430 (\u043f\u0440\u0438 \u043d\u0430\u043b\u0438\u0447\u0438\u0438 \u043e\u0442\u0432\u0435\u0442\u0430 \u0432 \u043a\u044d\u0448\u0435) \u0438\u043b\u0438 \u0438\u0437 \u0441\u0435\u0442\u0438 (\u043f\u0440\u0438 \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0438\u0438 \u043a\u044d\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0433\u043e \u043e\u0442\u0432\u0435\u0442\u0430). \u0421\u0435\u0442\u0435\u0432\u043e\u0439 \u0437\u0430\u043f\u0440\u043e\u0441 \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. \u0422\u0430\u043a\u043e\u0439 \u0437\u0430\u043f\u0440\u043e\u0441 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f \u043d\u0435\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e \u043e\u0442 \u0432\u043e\u0437\u0440\u0430\u0441\u0442\u0430 \u043a\u044d\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0433\u043e \u043e\u0442\u0432\u0435\u0442\u0430.<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">import { registerRoute } from 'workbox-routing' import { StaleWhileRevalidate } from 'workbox-strategies'  registerRoute(   ({url}) =&gt; url.pathname.startsWith('\/images\/avatars\/'),   new StaleWhileRevalidate() )<\/code><\/pre>\n<p>  <\/p>\n<h4 id=\"cache-fisrt\">Cache-Fisrt<\/h4>\n<p>  <\/p>\n<p>\u0414\u0430\u043d\u043d\u0430\u044f \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u044f \u043e\u0442\u043b\u0438\u0447\u043d\u043e \u043f\u043e\u0434\u0445\u043e\u0434\u0438\u0442 \u0434\u043b\u044f \u0431\u043e\u043b\u044c\u0448\u0438\u0445 \u0441\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u0440\u0435\u0434\u043a\u043e \u0438\u0437\u043c\u0435\u043d\u044f\u0435\u043c\u044b\u0445 \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432.<\/p>\n<p>  <\/p>\n<p>\u041f\u0440\u0438 \u043d\u0430\u043b\u0438\u0447\u0438\u0438 \u043e\u0442\u0432\u0435\u0442\u0430 \u0432 \u043a\u044d\u0448\u0435, \u043e\u043d \u043f\u0440\u043e\u0441\u0442\u043e \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442\u0441\u044f, \u0430 \u0441\u0435\u0442\u044c \u043d\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0441\u043e\u0432\u0441\u0435\u043c. \u0415\u0441\u043b\u0438 \u043e\u0442\u0432\u0435\u0442\u0430 \u0432 \u043a\u044d\u0448\u0435 \u043d\u0435\u0442, \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f \u0441\u0435\u0442\u0435\u0432\u043e\u0439 \u0437\u0430\u043f\u0440\u043e\u0441, \u043e\u0442\u0432\u0435\u0442 \u043d\u0430 \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442\u0441\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044e \u0438 \u043a\u044d\u0448\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0434\u043b\u044f \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0433\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f.<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">import { registerRoute } from 'workbox-routing' import { CacheFirst } from 'workbox-strategies'  registerRoute(   ({ request }) =&gt; request.destination === 'style',   new CacheFirst() )<\/code><\/pre>\n<p>  <\/p>\n<h4 id=\"network-first\">Network-First<\/h4>\n<p>  <\/p>\n<p>\u0414\u0430\u043d\u043d\u0430\u044f \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u044f \u043f\u043e\u0434\u0445\u043e\u0434\u0438\u0442 \u0434\u043b\u044f \u0447\u0430\u0441\u0442\u043e \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u043c\u044b\u0445 \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432. \u0421\u043d\u0430\u0447\u0430\u043b\u0430 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f \u0441\u0435\u0442\u0435\u0432\u043e\u0439 \u0437\u0430\u043f\u0440\u043e\u0441. \u0415\u0441\u043b\u0438 \u0437\u0430\u043f\u0440\u043e\u0441 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f \u0443\u0441\u043f\u0435\u0448\u043d\u043e, \u043e\u0442\u0432\u0435\u0442 \u043d\u0430 \u043d\u0435\u0433\u043e \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442\u0441\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044e \u0438 \u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0432 \u043a\u044d\u0448. \u0415\u0441\u043b\u0438 \u0437\u0430\u043f\u0440\u043e\u0441 \u043f\u0440\u043e\u0432\u0430\u043b\u0438\u0432\u0430\u0435\u0442\u0441\u044f, \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442\u0441\u044f \u043a\u044d\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u043e\u0442\u0432\u0435\u0442.<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">import { registerRoute } from 'workbox-routing' import { NetworkFirst } from 'workbox-strategies'  registerRoute(   ({ url }) =&gt; url.pathname.startsWith('\/social-timeline\/'),   new NetworkFirst() )<\/code><\/pre>\n<p>  <\/p>\n<h4 id=\"network-only\">Network-Only<\/h4>\n<p>  <\/p>\n<pre><code class=\"plaintext\">import { registerRoute } from 'workbox-routing' import { NetworkOnly } from 'workbox-strategies'  registerRoute(   ({url}) =&gt; url.pathname.startsWith('\/admin\/'),   new NetworkOnly() )<\/code><\/pre>\n<p>  <\/p>\n<h4 id=\"cache-only\">Cache-Only<\/h4>\n<p>  <\/p>\n<pre><code class=\"plaintext\">import { registerRoute } from 'workbox-routing' import { CacheOnly } from 'workbox-strategies'  registerRoute(   ({ url }) =&gt; url.pathname.startsWith('\/app\/v2\/'),   new CacheOnly() )<\/code><\/pre>\n<p>  <\/p>\n<h3 id=\"nastroyka-strategii\">\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u0438<\/h3>\n<p>  <\/p>\n<p>\u041a\u0430\u0436\u0434\u0430\u044f \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u044f \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043a\u0430\u0441\u0442\u043e\u043c\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c:<\/p>\n<p>  <\/p>\n<ul>\n<li>\u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u043a\u044d\u0448\u0430<\/li>\n<li>\u043b\u0438\u043c\u0438\u0442 \u0437\u0430\u043f\u0438\u0441\u0435\u0439 \u0432 \u043a\u044d\u0448\u0435 \u0438 \u0432\u0440\u0435\u043c\u044f \u0438\u0445 &quot;\u0436\u0438\u0437\u043d\u0438&quot;<\/li>\n<li>\u043f\u043b\u0430\u0433\u0438\u043d\u044b<\/li>\n<\/ul>\n<p>  <\/p>\n<p><strong>\u041d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u043a\u044d\u0448\u0430<\/strong><\/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: 'image-cache',   }) )<\/code><\/pre>\n<p>  <\/p>\n<p><strong>\u041f\u043b\u0430\u0433\u0438\u043d\u044b<\/strong><\/p>\n<p>  <\/p>\n<p>\u0412 \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u0438 \u043c\u043e\u0433\u0443\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \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>workbox-background-sync<\/code><\/li>\n<li><code>workbox-broadcast-update<\/code><\/li>\n<li><code>workbox-cacheable-response<\/code><\/li>\n<li><code>workbox-expiration<\/code><\/li>\n<li><code>workbox-range-requests<\/code><\/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: 'image-cache',     plugins: [       new ExpirationPlugin({         \/\/ \u0425\u0440\u0430\u043d\u0438\u0442\u044c \u0440\u0435\u0441\u0443\u0440\u0441\u044b \u0432 \u0442\u0435\u0447\u0435\u043d\u0438\u0435 \u043d\u0435\u0434\u0435\u043b\u0438         maxAgeSeconds: 7 * 24 * 60 * 60,         \/\/ \u0425\u0440\u0430\u043d\u0438\u0442\u044c \u0434\u043e 10 \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432         maxEntries: 10       })     ]   }) )<\/code><\/pre>\n<p>  <\/p>\n<p><code>WB<\/code> \u0442\u0430\u043a\u0436\u0435 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c <a href=\"https:\/\/developers.google.com\/web\/tools\/workbox\/modules\/workbox-strategies#custom_strategies\">\u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0435 \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u0438<\/a>.<\/p>\n<p>  <\/p>\n<h2 id=\"workbox-recipies\"><code>workbox-recipies<\/code><\/h2>\n<p>  <\/p>\n<p>\u041d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043f\u0430\u0442\u0442\u0435\u0440\u043d\u044b, \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e \u043a\u0430\u0441\u0430\u044e\u0449\u0438\u0435\u0441\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, \u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u043e\u0431\u0449\u0438\u043c\u0438 \u0434\u043b\u044f \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u0438\u0445 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u0438\u0437\u0430\u0446\u0438\u0438 \u0432 \u0432\u0438\u0434\u0435 \u043f\u0435\u0440\u0435\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u044b\u0445 \u0440\u0435\u0446\u0435\u043f\u0442\u043e\u0432. <code>workbox-recipies<\/code> \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u043d\u0430\u0431\u043e\u0440 \u0442\u0430\u043a\u0438\u0445 \u0440\u0435\u0446\u0435\u043f\u0442\u043e\u0432.<\/p>\n<p>  <\/p>\n<h3 id=\"recepty\">\u0420\u0435\u0446\u0435\u043f\u0442\u044b<\/h3>\n<p>  <\/p>\n<p>\u041a\u0430\u0436\u0434\u044b\u0439 \u0440\u0435\u0446\u0435\u043f\u0442 \u2014 \u044d\u0442\u043e \u043a\u043e\u043c\u0431\u0438\u043d\u0430\u0446\u0438\u044f \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u044b\u0445 \u043c\u043e\u0434\u0443\u043b\u0435\u0439 <code>WB<\/code>. \u041d\u0438\u0436\u0435 \u043f\u0440\u0438\u0432\u043e\u0434\u044f\u0442\u0441\u044f \u0440\u0435\u0446\u0435\u043f\u0442\u044b \u0438 \u043f\u0430\u0442\u0442\u0435\u0440\u043d\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043e\u043d\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442 \u043f\u043e\u0434 \u043a\u0430\u043f\u043e\u0442\u043e\u043c, \u043d\u0430 \u0441\u043b\u0443\u0447\u0430\u0439, \u0435\u0441\u043b\u0438 \u0432\u044b \u0437\u0430\u0445\u043e\u0442\u0438\u0442\u0435 \u043a\u0430\u0441\u0442\u043e\u043c\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0442\u043e\u0442 \u0438\u043b\u0438 \u0438\u043d\u043e\u0439 \u0440\u0435\u0446\u0435\u043f\u0442.<\/p>\n<p>  <\/p>\n<h4 id=\"rezervnyy-kontent\">\u0420\u0435\u0437\u0435\u0440\u0432\u043d\u044b\u0439 \u043a\u043e\u043d\u0442\u0435\u043d\u0442<\/h4>\n<p>  <\/p>\n<p>\u0414\u0430\u043d\u043d\u044b\u0439 \u0440\u0435\u0446\u0435\u043f\u0442 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0421\u0412 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0442\u044c \u0440\u0435\u0437\u0435\u0440\u0432\u043d\u0443\u044e \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443, \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u0438\u043b\u0438 \u0448\u0440\u0438\u0444\u0442 \u043f\u0440\u0438 \u0432\u043e\u0437\u043d\u0438\u043a\u043d\u043e\u0432\u0435\u043d\u0438\u0438 \u043e\u0448\u0438\u0431\u043a\u0438 \u043f\u0440\u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0438 \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u043d\u0430 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u043b\u044e\u0431\u043e\u0433\u043e \u0438\u0437 \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u044b\u0445 \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432.<\/p>\n<p>  <\/p>\n<p>\u041f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e \u0440\u0435\u0437\u0435\u0440\u0432\u043d\u0430\u044f \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430 \u0434\u043e\u043b\u0436\u043d\u0430 \u0438\u043c\u0435\u0442\u044c \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 <code>offline.html<\/code>.<\/p>\n<p>  <\/p>\n<p>\u0420\u0435\u0437\u0435\u0440\u0432\u043d\u044b\u0439 \u043a\u043e\u043d\u0442\u0435\u043d\u0442 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442\u0441\u044f \u043f\u0440\u0438 \u0441\u043e\u0432\u043f\u0430\u0434\u0435\u043d\u0438\u0438 \u0441 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u044b\u043c \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u043c. \u041f\u0440\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0438 \u0440\u0430\u0441\u0441\u043c\u0430\u0442\u0440\u0438\u0432\u0430\u0435\u043c\u043e\u0433\u043e \u0440\u0435\u0446\u0435\u043f\u0442\u0430 \u0432 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438, \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0435 \u0440\u043e\u0443\u0442\u044b. \u041f\u0440\u043e\u0441\u0442\u0435\u0439\u0448\u0438\u043c \u0441\u043f\u043e\u0441\u043e\u0431\u043e\u043c \u044d\u0442\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u043c\u0435\u0442\u043e\u0434\u0430 <code>setDefaultHandler()<\/code> \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0440\u043e\u0443\u0442\u0430, \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u044e\u0449\u0435\u0433\u043e \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u044e &quot;\u0442\u043e\u043b\u044c\u043a\u043e \u0441\u0435\u0442\u044c&quot; \u0432 \u043e\u0442\u043d\u043e\u0448\u0435\u043d\u0438\u0438 \u0432\u0441\u0435\u0445 \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432.<\/p>\n<p>  <\/p>\n<p><strong>\u0420\u0435\u0446\u0435\u043f\u0442<\/strong><\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">import { offlineFallback } from 'workbox-recipes' import { setDefaultHandler } from 'workbox-routing' import { NetworkOnly } from 'workbox-strategies'  setDefaultHandler(   new NetworkOnly() )  offlineFallback()<\/code><\/pre>\n<p>  <\/p>\n<p><strong>\u041f\u0430\u0442\u0442\u0435\u0440\u043d<\/strong><\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">import { setCatchHandler, setDefaultHandler } from 'workbox-routing' import { NetworkOnly } from 'workbox-strategies'  const pageFallback = 'offline.html' const imageFallback = false const fontFallback = false  setDefaultHandler(   new NetworkOnly() )  self.addEventListener('install', event =&gt; {   const files = [pageFallback]   if (imageFallback) {     files.push(imageFallback)   }   if (fontFallback) {     files.push(fontFallback)   }    event.waitUntil(self.caches.open('workbox-offline-fallbacks').then(cache =&gt; cache.addAll(files))) })  const handler = async (options) =&gt; {   const dest = options.request.destination   const cache = await self.caches.open('workbox-offline-fallbacks')    if (dest === 'document') {     return (await cache.match(pageFallback)) || Response.error()   }    if (dest === 'image' &amp;&amp; imageFallback !== false) {     return (await cache.match(imageFallback)) || Response.error()   }    if (dest === 'font' &amp;&amp; fontFallback !== false) {     return (await cache.match(fontFallback)) || Response.error()   }    return Response.error() }  setCatchHandler(handler)<\/code><\/pre>\n<p>  <\/p>\n<h3 id=\"podgotovka-kesha\">\u041f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u043a\u0430 \u043a\u044d\u0448\u0430<\/h3>\n<p>  <\/p>\n<p>\u0414\u0430\u043d\u043d\u044b\u0439 \u0440\u0435\u0446\u0435\u043f\u0442 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0442\u044c \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u044b\u0435 <code>URL<\/code> \u0432 \u043a\u044d\u0448 \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438 \u0421\u0412. \u041e\u043d\u0430 \u043c\u043e\u0436\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0430\u043b\u044c\u0442\u0435\u0440\u043d\u0430\u0442\u0438\u0432\u044b \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 \u0432 \u0441\u043b\u0443\u0447\u0430\u0435, \u043a\u043e\u0433\u0434\u0430 \u043d\u0430\u043c \u0437\u0430\u0440\u0430\u043d\u0435\u0435 \u0438\u0437\u0432\u0435\u0441\u0442\u0435\u043d \u0441\u043f\u0438\u0441\u043e\u043a <code>URL<\/code> \u0434\u043b\u044f \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f.<\/p>\n<p>  <\/p>\n<p><strong>\u0420\u0435\u0446\u0435\u043f\u0442<\/strong><\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">import { warmStrategyCache } from 'workbox-recipes' import { CacheFirst } from 'workbox-strategies'  \/\/ \u0417\u0434\u0435\u0441\u044c \u043c\u043e\u0436\u0435\u0442 \u0438\u0441\u043f\u043e\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u043b\u044e\u0431\u0430\u044f \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u044f const strategy = new CacheFirst() const urls = [   '\/offline.html' ]  warmStrategyCache({urls, strategy})<\/code><\/pre>\n<p>  <\/p>\n<p><strong>\u041f\u0430\u0442\u0442\u0435\u0440\u043d<\/strong><\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">import { CacheFirst } from 'workbox-strategies' \/\/ \u0417\u0434\u0435\u0441\u044c \u043c\u043e\u0436\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u043b\u044e\u0431\u0430\u044f \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u044f const strategy = new CacheFirst() const urls = [   '\/offline.html', ]  self.addEventListener('install', event =&gt; {   \/\/ `handleAll` \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0434\u0432\u0430 \u043f\u0440\u043e\u043c\u0438\u0441\u0430, \u0432\u0442\u043e\u0440\u043e\u0439 \u043f\u0440\u043e\u043c\u0438\u0441 \u0440\u0430\u0437\u0440\u0435\u0448\u0430\u0435\u0442\u0441\u044f \u043f\u043e\u0441\u043b\u0435 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0432\u0441\u0435\u0445 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 \u0432 \u043a\u044d\u0448   const done = urls.map(path =&gt; strategy.handleAll({     event,     request: new Request(path),   })[1])    event.waitUntil(Promise.all(done)) })<\/code><\/pre>\n<p>  <\/p>\n<h3 id=\"keshirovanie-stranicy\">\u041a\u044d\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b<\/h3>\n<p>  <\/p>\n<p>\u0414\u0430\u043d\u043d\u044b\u0439 \u0440\u0435\u0446\u0435\u043f\u0442 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0421\u0412 \u043e\u0442\u0432\u0435\u0447\u0430\u0442\u044c \u043d\u0430 \u0437\u0430\u043f\u0440\u043e\u0441 \u043d\u0430 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 <code>HTML-\u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b<\/code> \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u0438 &quot;\u0441\u043d\u0430\u0447\u0430\u043b\u0430 \u0441\u0435\u0442\u044c&quot;. \u041f\u0440\u0438 \u044d\u0442\u043e\u043c, \u0421\u0412 \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0442\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c, \u0447\u0442\u043e \u0432 \u0441\u043b\u0443\u0447\u0430\u0435 \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0438\u044f \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u043a \u0441\u0435\u0442\u0438, \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u043e\u0442\u0432\u0435\u0442 \u0438\u0437 \u043a\u044d\u0448\u0430 \u043c\u0435\u043d\u0435\u0435 \u0447\u0435\u043c \u0437\u0430 4 \u0441\u0435\u043a\u0443\u043d\u0434\u044b. \u041f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e \u0437\u0430\u043f\u0440\u043e\u0441 \u043a \u0441\u0435\u0442\u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f \u0432 \u0442\u0435\u0447\u0435\u043d\u0438\u0435 3 \u0441\u0435\u043a\u0443\u043d\u0434. \u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 <code>warmCache<\/code> \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u0438\u0442\u044c (&quot;\u0440\u0430\u0437\u043e\u0433\u0440\u0435\u0442\u044c&quot;) \u043a\u044d\u0448 \u043a \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044e.<\/p>\n<p>  <\/p>\n<p><strong>\u0420\u0435\u0446\u0435\u043f\u0442<\/strong><\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">import { pageCache } from 'workbox-recipes'  pageCache()<\/code><\/pre>\n<p>  <\/p>\n<p><strong>\u041f\u0430\u0442\u0442\u0435\u0440\u043d<\/strong><\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">import { registerRoute } from 'workbox-routing' import { NetworkFirst } from 'workbox-strategies' import { CacheableResponsePlugin } from 'workbox-cacheable-response'  const cacheName = 'pages' const matchCallback = ({ request }) =&gt; request.mode === 'navigate' const networkTimeoutSeconds = 3  registerRoute(   matchCallback,   new NetworkFirst({     networkTimeoutSeconds,     cacheName,     plugins: [       new CacheableResponsePlugin({         statuses: [0, 200]       })     ]   }) )<\/code><\/pre>\n<p>  <\/p>\n<h3 id=\"keshirovanie-staticheskih-resursov\">\u041a\u044d\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0441\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432<\/h3>\n<p>  <\/p>\n<p>\u0414\u0430\u043d\u043d\u044b\u0439 \u0440\u0435\u0446\u0435\u043f\u0442 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0421\u0412 \u043e\u0442\u0432\u0435\u0447\u0430\u0442\u044c \u043d\u0430 \u0437\u0430\u043f\u0440\u043e\u0441\u044b \u043d\u0430 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 \u0441\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432, \u0442\u0430\u043a\u0438\u0445 \u043a\u0430\u043a <code>JavaScript<\/code>, <code>CSS<\/code> \u0438 \u0432\u0435\u0431-\u0432\u043e\u0440\u043a\u0435\u0440\u044b \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u0438 &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; (\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 \u043a\u044d\u0448 \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u0442\u0441\u044f). \u041f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0440\u0430\u0437\u043e\u0433\u0440\u0435\u0432 \u043a\u044d\u0448\u0430 (<code>warmCache<\/code>).<\/p>\n<p>  <\/p>\n<p><strong>\u0420\u0435\u0446\u0435\u043f\u0442<\/strong><\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">import { staticResourceCache } from 'workbox-recipes'  staticResourceCache()<\/code><\/pre>\n<p>  <\/p>\n<p><strong>\u041f\u0430\u0442\u0442\u0435\u0440\u043d<\/strong><\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">import { registerRoute } from 'workbox-routing' import { StaleWhileRevalidate } from 'workbox-strategies' import { CacheableResponsePlugin } from 'workbox-cacheable-response'  const cacheName = 'static-resources' const matchCallback = ({ request }) =&gt;   \/\/ CSS   request.destination === 'style' ||   \/\/ JavaScript   request.destination === 'script' ||   \/\/ \u0432\u0435\u0431-\u0432\u043e\u0440\u043a\u0435\u0440\u044b   request.destination === 'worker'  registerRoute(   matchCallback,   new StaleWhileRevalidate({     cacheName,     plugins: [       new CacheableResponsePlugin({         statuses: [0, 200]       })     ]   }) )<\/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>\u0414\u0430\u043d\u043d\u044b\u0439 \u0440\u0435\u0446\u0435\u043f\u0442 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0421\u0412 \u043e\u0442\u0432\u0435\u0447\u0430\u0442\u044c \u043d\u0430 \u0437\u0430\u043f\u0440\u043e\u0441\u044b \u043d\u0430 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0439 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u0438 &quot;\u0441\u043d\u0430\u0447\u0430\u043b\u0430 \u043a\u044d\u0448&quot;. \u041f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e \u043a\u044d\u0448\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0434\u043e 60 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0439 \u0432 \u0442\u0435\u0447\u0435\u043d\u0438\u0435 30 \u0434\u043d\u0435\u0439. \u041f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0440\u0430\u0437\u043e\u0433\u0440\u0435\u0432 \u043a\u044d\u0448\u0430.<\/p>\n<p>  <\/p>\n<p><strong>\u0420\u0435\u0446\u0435\u043f\u0442<\/strong><\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">import { imageCache } from 'workbox-recipes'  imageCache()<\/code><\/pre>\n<p>  <\/p>\n<p><strong>\u041f\u0430\u0442\u0442\u0435\u0440\u043d<\/strong><\/p>\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'  const cacheName = 'images' const matchCallback = ({ request }) =&gt; request.destination === 'image' const maxAgeSeconds = 30 * 24 * 60 * 60 const maxEntries = 60  registerRoute(   matchCallback,   new CacheFirst({     cacheName,     plugins: [       new CacheableResponsePlugin({         statuses: [0, 200]       }),       new ExpirationPlugin({         maxEntries,         maxAgeSeconds       })     ]   }) )<\/code><\/pre>\n<p>  <\/p>\n<h3 id=\"keshirovanie-gugl-shriftov\">\u041a\u044d\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0433\u0443\u0433\u043b-\u0448\u0440\u0438\u0444\u0442\u043e\u0432<\/h3>\n<p>  <\/p>\n<p>\u0414\u0430\u043d\u043d\u044b\u0439 \u0440\u0435\u0446\u0435\u043f\u0442 \u043a\u044d\u0448\u0438\u0440\u0443\u0435\u0442 \u0442\u0430\u0431\u043b\u0438\u0446\u0443 \u0441\u0442\u0438\u043b\u0435\u0439 \u0434\u043b\u044f \u0448\u0440\u0438\u0444\u0442\u043e\u0432 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u0438 &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; \u0438 \u0441\u0430\u043c\u0438 \u0448\u0440\u0438\u0444\u0442\u044b \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u0438 &quot;\u0441\u043d\u0430\u0447\u0430\u043b\u0430 \u043a\u044d\u0448&quot;. \u041f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e \u043a\u044d\u0448\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0434\u043e 30 \u0448\u0440\u0438\u0444\u0442\u043e\u0432 \u0432 \u0442\u0435\u0447\u0435\u043d\u0438\u0435 1 \u0433\u043e\u0434\u0430.<\/p>\n<p>  <\/p>\n<p><strong>\u0420\u0435\u0446\u0435\u043f\u0442<\/strong><\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">import { googleFontsCache } from 'workbox-recipes'  googleFontsCache()<\/code><\/pre>\n<p>  <\/p>\n<p><strong>\u041f\u0430\u0442\u0442\u0435\u0440\u043d<\/strong><\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">import { registerRoute } from 'workbox-routing' import { StaleWhileRevalidate } from 'workbox-strategies' import { CacheFirst } from 'workbox-strategies' import { CacheableResponsePlugin } from 'workbox-cacheable-response' import { ExpirationPlugin } from 'workbox-expiration'  const sheetCacheName = 'google-fonts-stylesheets' const fontCacheName = 'google-fonts-webfonts' const maxAgeSeconds = 60 * 60 * 24 * 365 const maxEntries = 30  registerRoute(   ({ url }) =&gt; url.origin === 'https:\/\/fonts.googleapis.com',   new StaleWhileRevalidate({     cacheName: sheetCacheName   }) )  \/\/ \u041a\u044d\u0448\u0438\u0440\u0443\u0435\u043c \u0434\u043e 30 \u0448\u0440\u0438\u0444\u0442\u043e\u0432 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u0438 &quot;\u0441\u043d\u0430\u0447\u0430\u043b\u0430 \u043a\u044d\u0448&quot; \u0438 \u0445\u0440\u0430\u043d\u0438\u043c \u043a\u044d\u0448 \u0432 \u0442\u0435\u0447\u0435\u043d\u0438\u0435 1 \u0433\u043e\u0434\u0430 registerRoute(   ({ url }) =&gt; url.origin === 'https:\/\/fonts.gstatic.com',   new CacheFirst({     cacheName: fontCacheName,     plugins: [       new CacheableResponsePlugin({         statuses: [0, 200],       }),       new ExpirationPlugin({         maxAgeSeconds,         maxEntries       })     ]   }) )<\/code><\/pre>\n<p>  <\/p>\n<h3 id=\"bystroe-ispolzovanie\">\u0411\u044b\u0441\u0442\u0440\u043e\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435<\/h3>\n<p>  <\/p>\n<p>\u041a\u043e\u043c\u0431\u0438\u043d\u0430\u0446\u0438\u044f \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0435\u043d\u043d\u044b\u0445 \u0440\u0435\u0446\u0435\u043f\u0442\u043e\u0432 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0421\u0412, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u043e\u0442\u0432\u0435\u0447\u0430\u0442\u044c \u043d\u0430 \u043d\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u0435 \u0437\u0430\u043f\u0440\u043e\u0441\u044b \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u0438 &quot;\u0441\u043d\u0430\u0447\u0430\u043b\u0430 \u0441\u0435\u0442\u044c&quot;, \u043d\u0430 \u0437\u0430\u043f\u0440\u043e\u0441\u044b \u043d\u0430 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 \u0441\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u0438 &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;, \u043d\u0430 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0439 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u0438 &quot;\u0441\u043d\u0430\u0447\u0430\u043b\u0430 \u043a\u044d\u0448&quot;. \u041e\u043d \u0442\u0430\u043a\u0436\u0435 \u0431\u0443\u0434\u0435\u0442 \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c \u0433\u0443\u0433\u043b-\u0448\u0440\u0438\u0444\u0442\u044b \u0438 \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0442\u044c \u0440\u0435\u0437\u0435\u0440\u0432\u043d\u044b\u0439 \u043a\u043e\u043d\u0442\u0435\u043d\u0442 \u0432 \u0441\u043b\u0443\u0447\u0430\u0435 \u0432\u043e\u0437\u043d\u0438\u043a\u043d\u043e\u0432\u0435\u043d\u0438\u044f \u043e\u0448\u0438\u0431\u043a\u0438. \u0412\u043e\u0442 \u043a\u0430\u043a \u044d\u0442\u043e \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442:<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">import {   pageCache,   imageCache,   staticResourceCache,   googleFontsCache,   offlineFallback } from 'workbox-recipes'  pageCache()  googleFontsCache()  staticResourceCache()  imageCache()  offlineFallback()<\/code><\/pre>\n<p>  <\/p>\n<h2 id=\"workbox-window\"><code>workbox-window<\/code><\/h2>\n<p>  <\/p>\n<p>\u0414\u0430\u043d\u043d\u044b\u0439 \u043c\u043e\u0434\u0443\u043b\u044c \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f \u0432 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0435 <code>window<\/code>. \u0415\u0433\u043e \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u043c\u0438 \u0437\u0430\u0434\u0430\u0447\u0430\u043c\u0438 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0435:<\/p>\n<p>  <\/p>\n<ul>\n<li>\u0443\u043f\u0440\u043e\u0449\u0435\u043d\u0438\u0435 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0430 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u0438 \u0438 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f \u0421\u0412 \u0432 \u043d\u0430\u0438\u0431\u043e\u043b\u0435\u0435 \u043f\u043e\u0434\u0445\u043e\u0434\u044f\u0449\u0438\u0435 \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043c\u043e\u043c\u0435\u043d\u0442\u044b \u0436\u0438\u0437\u043d\u0435\u043d\u043d\u043e\u0433\u043e \u0446\u0438\u043a\u043b\u0430 \u0421\u0412<\/li>\n<li>\u043f\u043e\u043c\u043e\u0449\u044c \u0432 \u043e\u0431\u043d\u0430\u0440\u0443\u0436\u0435\u043d\u0438\u0438 \u043d\u0430\u0438\u0431\u043e\u043b\u0435\u0435 \u0440\u0430\u0441\u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0435\u043d\u043d\u044b\u0445 \u043e\u0448\u0438\u0431\u043e\u043a, \u0441\u043e\u0432\u0435\u0440\u0448\u0430\u0435\u043c\u044b\u0445 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0430\u043c\u0438 \u043f\u0440\u0438 \u0440\u0430\u0431\u043e\u0442\u0435 \u0441 \u0421\u0412<\/li>\n<li>\u043e\u0431\u043b\u0435\u0433\u0447\u0435\u043d\u0438\u0435 \u043a\u043e\u043c\u043c\u0443\u043d\u0438\u043a\u0430\u0446\u0438\u0438 \u043c\u0435\u0436\u0434\u0443 \u043a\u043e\u0434\u043e\u043c \u0421\u0412 \u0438 \u043a\u043e\u0434\u043e\u043c, \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c\u044b\u043c \u0432 <code>window<\/code><\/li>\n<\/ul>\n<p>  <\/p>\n<h3 id=\"ispolzovanie-cdn\">\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 CDN<\/h3>\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')    wb.register() } &lt;\/script&gt;<\/code><\/pre>\n<p>  <\/p>\n<h3 id=\"ispolzovanie-sborschika-moduley\">\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u0441\u0431\u043e\u0440\u0449\u0438\u043a\u0430 \u043c\u043e\u0434\u0443\u043b\u0435\u0439<\/h3>\n<p>  <\/p>\n<p><strong>\u0423\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430<\/strong><\/p>\n<p>  <\/p>\n<pre><code class=\"bash\">yarn add workbox-window # \u0438\u043b\u0438 npm i workbox-window<\/code><\/pre>\n<p>  <\/p>\n<p><strong>\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435<\/strong><\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">import { Workbox } from 'workbox-window'  if ('serviceWorker' in navigator) {   const wb = new Workbox('\/sw.js')    wb.register() }<\/code><\/pre>\n<p>  <\/p>\n<h3 id=\"primery\">\u041f\u0440\u0438\u043c\u0435\u0440\u044b<\/h3>\n<p>  <\/p>\n<p><strong>\u0420\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u044f \u0421\u0412 \u0438 \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u0435 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u043e \u0435\u0433\u043e \u0430\u043a\u0442\u0438\u0432\u0430\u0446\u0438\u0438<\/strong><\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">const wb = new Workbox('\/sw.js')  wb.addEventListener('activated', (event) =&gt; {   \/\/ `event.isUpdate` \u0431\u0443\u0434\u0435\u0442 \u0438\u043c\u0435\u0442\u044c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 `true`, \u0435\u0441\u043b\u0438 \u0434\u0440\u0443\u0433\u0430\u044f \u0432\u0435\u0440\u0441\u0438\u044f \u0421\u0412   \/\/ \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0435\u0439 \u043f\u0440\u0438 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u0438 \u0434\u0430\u043d\u043d\u043e\u0439 \u0432\u0435\u0440\u0441\u0438\u0438   if (!event.isUpdate) {     console.log('\u0421\u0412 \u0431\u044b\u043b \u0430\u043a\u0442\u0438\u0432\u0438\u0440\u043e\u0432\u0430\u043d \u0432 \u043f\u0435\u0440\u0432\u044b\u0439 \u0440\u0430\u0437!')      \/\/ \u0415\u0441\u043b\u0438 \u0421\u0412 \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043d \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,     \/\/ \u044d\u0442\u0438 \u0440\u0435\u0441\u0443\u0440\u0441\u044b \u043c\u043e\u0433\u0443\u0442 \u0431\u044b\u0442\u044c \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u044b \u0437\u0434\u0435\u0441\u044c   } })  \/\/ \u0420\u0435\u0433\u0438\u0441\u0442\u0440\u0443\u0435\u043c \u0421\u0412 \u043f\u043e\u0441\u043b\u0435 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u043e\u0432 \u0441\u043e\u0431\u044b\u0442\u0438\u0439 wb.register()<\/code><\/pre>\n<p>  <\/p>\n<p><strong>\u0423\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u0435 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u043e \u0442\u043e\u043c, \u0447\u0442\u043e \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<\/strong><\/p>\n<p>  <\/p>\n<p>\u041a\u043e\u0433\u0434\u0430 \u043d\u0430 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0435, \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u043c\u043e\u0439 \u0421\u0412, \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0443\u0435\u0442\u0441\u044f \u043d\u043e\u0432\u044b\u0439 \u0421\u0412, \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0439 \u043d\u0435 \u0431\u0443\u0434\u0435\u0442 \u0430\u043a\u0442\u0438\u0432\u0438\u0440\u043e\u0432\u0430\u043d \u0434\u043e \u0442\u0435\u0445 \u043f\u043e\u0440, \u043f\u043e\u043a\u0430 \u0432\u0441\u0435 \u043a\u043b\u0438\u0435\u043d\u0442\u044b, \u043a\u043e\u043d\u0442\u0440\u043b\u0438\u0440\u0443\u0435\u043c\u044b\u0435 \u043f\u0435\u0440\u0432\u044b\u043c, \u043d\u0435 \u0437\u0430\u0432\u0435\u0440\u0448\u0430\u0442 \u0441\u0432\u043e\u0438 \u0441\u0435\u0441\u0441\u0438\u0438.<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">const wb = new Workbox('\/sw.js')  wb.addEventListener('waiting', (event) =&gt; {   console.log(     `\u041d\u043e\u0432\u044b\u0439 \u0421\u0412 \u0431\u044b\u043b \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d, \u043d\u043e \u043e\u043d \u043d\u0435 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0430\u043a\u0442\u0438\u0432\u0438\u0440\u043e\u0432\u0430\u043d, \u043f\u043e\u043a\u0430 \u0432\u0441\u0435 \u0432\u043a\u043b\u0430\u0434\u043a\u0438 \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0430 \u043d\u0435 \u0431\u0443\u0434\u0443\u0442 \u0437\u0430\u043a\u0440\u044b\u0442\u044b \u0438\u043b\u0438 \u043f\u0435\u0440\u0435\u0437\u0430\u0433\u0440\u0443\u0436\u0435\u043d\u044b`   ) })  wb.register()<\/code><\/pre>\n<p>  <\/p>\n<p><strong>\u0423\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u0435 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u043e\u0431 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0438 \u043a\u044d\u0448\u0430<\/strong><\/p>\n<p>  <\/p>\n<p>\u041c\u043e\u0434\u0443\u043b\u044c <code>workbox-broadcast-update<\/code> \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0438\u043d\u0444\u043e\u0440\u043c\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439 \u043e\u0431 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0438 \u043a\u043e\u043d\u0442\u0435\u043d\u0442\u0430. \u0414\u043b\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u044d\u0442\u043e\u0439 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438 \u0432 \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0441\u043e\u0431\u044b\u0442\u0438\u0435 <code>message<\/code> \u0441 \u0442\u0438\u043f\u043e\u043c <code>CACHE_UPDATED<\/code>:<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">const wb = new Workbox('\/sw.js')  wb.addEventListener('message', (event) =&gt; {   if (event.data.type === 'CACHE_UPDATED') {     const { updatedURL } = event.data.payload      console.log(`\u0414\u043e\u0441\u0442\u0443\u043f\u043d\u0430 \u043d\u043e\u0432\u0430\u044f \u0432\u0435\u0440\u0441\u0438\u044f ${updatedURL}!`)   } })  wb.register()<\/code><\/pre>\n<p>  <\/p>\n<p><strong>\u041e\u0442\u043f\u0440\u0430\u0432\u043a\u0430 \u0421\u0412 \u0441\u043f\u0438\u0441\u043a\u0430 URL \u0434\u043b\u044f \u043a\u044d\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f<\/strong><\/p>\n<p>  <\/p>\n<p>\u0412 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f\u0445 \u0438\u043c\u0435\u0435\u0442 \u0441\u043c\u044b\u0441\u043b \u043a\u044d\u0448\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u0442\u0435 \u0440\u0435\u0441\u0443\u0440\u0441\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442\u0441\u044f \u043f\u043e\u0441\u0435\u0449\u0435\u043d\u043d\u043e\u0439 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u043c \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0435\u0439. \u041c\u043e\u0434\u0443\u043b\u044c <code>workbox-routing<\/code> \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u0441\u043f\u0438\u0441\u043e\u043a <code>URL<\/code> \u0438 \u043a\u044d\u0448\u0438\u0440\u0443\u0435\u0442 \u0438\u0445 \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u043f\u0440\u0430\u0432\u0438\u043b, \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u044b\u0445 \u0432 \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0438\u0437\u0430\u0442\u043e\u0440\u0435.<\/p>\n<p>  <\/p>\n<p>\u0412 \u043f\u0440\u0438\u0432\u0435\u0434\u0435\u043d\u043d\u043e\u043c \u043d\u0438\u0436\u0435 \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u043f\u0440\u0438 \u043a\u0430\u0436\u0434\u043e\u0439 \u0430\u043a\u0442\u0438\u0432\u0430\u0446\u0438\u0438 \u043d\u043e\u0432\u043e\u0433\u043e \u0421\u0412 \u0432 \u0440\u043e\u0443\u0442\u0435\u0440 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0441\u043f\u0438\u0441\u043e\u043a <code>URL<\/code> \u0434\u043b\u044f \u043a\u044d\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f. <em>\u041e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435<\/em>, \u0447\u0442\u043e \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c \u0432\u0441\u0435 <code>URL<\/code>, \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u0431\u0443\u0434\u0443\u0442 \u043a\u044d\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u044b \u0442\u043e\u043b\u044c\u043a\u043e \u0442\u0435 \u0438\u0437 \u043d\u0438\u0445, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0441\u043e\u0432\u043f\u0430\u0434\u0443\u0442 \u0441 \u0440\u043e\u0443\u0442\u0430\u043c\u0438.<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">const wb = new Workbox('\/sw.js')  wb.addEventListener('activated', (event) =&gt; {   \/\/ \u041f\u043e\u043b\u0443\u0447\u0430\u0435\u043c `URL` \u0442\u0435\u043a\u0443\u0449\u0435\u0439 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b + \u0432\u0441\u0435 \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0435\u043c\u044b\u0435 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0435\u0439 \u0440\u0435\u0441\u0443\u0440\u0441\u044b   const urlsToCache = [     location.href,     ...performance       .getEntriesByType('resource')       .map((r) =&gt; r.name)   ]   \/\/ \u041f\u0435\u0440\u0435\u0434\u0430\u0435\u043c \u044d\u0442\u043e\u0442 \u0441\u043f\u0438\u0441\u043e\u043a \u0421\u0412   wb.messageSW({     type: 'CACHE_URLS',     payload: { urlsToCache }   }) })  wb.register()<\/code><\/pre>\n<p>  <\/p>\n<h2 id=\"praktika\">\u041f\u0440\u0430\u043a\u0442\u0438\u043a\u0430<\/h2>\n<p>  <\/p>\n<p>\u0412 \u044d\u0442\u043e\u043c \u0440\u0430\u0437\u0434\u0435\u043b\u0435 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u043e \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 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0432 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f\u0445 &quot;\u043a\u0430\u043a \u0435\u0441\u0442\u044c&quot;, \u0430 \u0442\u0430\u043a\u0436\u0435 \u043a\u0440\u0430\u0442\u043a\u0438\u0439 \u043e\u0431\u0437\u043e\u0440 \u0433\u043e\u0442\u043e\u0432\u044b\u0445 \u0440\u0435\u0448\u0435\u043d\u0438\u0439 \u0434\u043b\u044f \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 <code>PWA<\/code>, \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u043c\u044b\u0445 \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<p>\u0414\u043b\u044f \u043e\u0431\u0435\u0441\u043f\u0435\u0447\u0435\u043d\u0438\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0432 \u0440\u0435\u0436\u0438\u043c\u0435 \u043e\u0444\u043b\u0430\u0439\u043d \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u0421\u0412 \u0438 \u0435\u0433\u043e \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u044f \u0432 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0439 \u0444\u0430\u0439\u043b\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f, \u043d\u043e \u0438 \u0442\u0430\u043a \u043d\u0430\u0437\u044b\u0432\u0430\u0435\u043c\u044b\u0439 &quot;\u043c\u0430\u043d\u0438\u0444\u0435\u0441\u0442&quot;.<\/p>\n<p>  <\/p>\n<p>\u041e \u0442\u043e\u043c, \u0447\u0442\u043e \u0442\u0430\u043a\u043e\u0435 \u043c\u0430\u043d\u0438\u0444\u0435\u0441\u0442 \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0447\u0438\u0442\u0430\u0442\u044c <a href=\"https:\/\/web.dev\/add-manifest\/\">\u0437\u0434\u0435\u0441\u044c<\/a>, <a href=\"https:\/\/developer.mozilla.org\/ru\/docs\/Web\/Manifest\">\u0437\u0434\u0435\u0441\u044c<\/a> \u0438 <a href=\"https:\/\/www.w3.org\/TR\/appmanifest\/\">\u0437\u0434\u0435\u0441\u044c<\/a>.<\/p>\n<p>  <\/p>\n<p>\u041a\u0430\u043a \u043f\u0440\u0430\u0432\u0438\u043b\u043e, \u043c\u0430\u043d\u0438\u0444\u0435\u0441\u0442 (\u0438 \u0421\u0412) \u0440\u0430\u0437\u043c\u0435\u0449\u0430\u044e\u0442\u0441\u044f \u043d\u0430 \u0432\u0435\u0440\u0445\u043d\u0435\u043c \u0443\u0440\u043e\u0432\u043d\u0435 (\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. \u041c\u0430\u043d\u0438\u0444\u0435\u0441\u0442 \u043c\u043e\u0436\u0435\u0442 \u0438\u043c\u0435\u0442\u044c \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u0435 <code>.json<\/code> \u0438\u043b\u0438 <code>.webmanifest<\/code> (\u043b\u0443\u0447\u0448\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043f\u0435\u0440\u0432\u044b\u0439 \u0432\u0430\u0440\u0438\u0430\u043d\u0442).<\/p>\n<p>  <\/p>\n<p><strong>\u041c\u0430\u043d\u0438\u0444\u0435\u0441\u0442<\/strong><\/p>\n<p>  <\/p>\n<pre><code class=\"json\">{   &quot;name&quot;: &quot;\u041d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f&quot;,   &quot;short_name&quot;: &quot;\u041a\u0440\u0430\u0442\u043a\u043e\u0435 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 (\u0431\u0443\u0434\u0435\u0442 \u0443\u043a\u0430\u0437\u0430\u043d\u043e \u043f\u043e\u0434 \u0438\u043a\u043e\u043d\u043a\u043e\u0439 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u043f\u0440\u0438 \u0435\u0433\u043e \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0435)&quot;,   &quot;scope&quot;: &quot;\/&quot;, \/\/ \u0437\u043e\u043d\u0430 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u044f \u0421\u0412, \u0440\u0430\u0437\u043d\u044b\u0435 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b \u043c\u043e\u0433\u0443\u0442 \u043e\u0431\u0441\u043b\u0443\u0436\u0438\u0432\u0430\u0442\u044c\u0441\u044f \u0440\u0430\u0437\u043d\u044b\u043c\u0438 \u0421\u0412   &quot;start_url&quot;: &quot;.&quot;, \/\/ \u043d\u0430\u0447\u0430\u043b\u044c\u043d\u044b\u0439 URL, \u043a\u0430\u043a \u043f\u0440\u0430\u0432\u0438\u043b\u043e, \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044f, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f index.html, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0421\u0412   &quot;display&quot;: &quot;standalone&quot;,   &quot;orientation&quot;: &quot;portrait&quot;,   &quot;background_color&quot;: &quot;#f0f0f0&quot;,   &quot;theme_color&quot;: &quot;#3c3c3c&quot;,   &quot;description&quot;: &quot;\u041e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f&quot;,   \/\/ \u044d\u0442\u0438\u0445 \u0438\u043a\u043e\u043d\u043e\u043a \u0434\u043e\u043b\u0436\u043d\u043e \u0431\u044b\u0442\u044c \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0434\u043b\u044f \u0431\u043e\u043b\u044c\u0448\u0438\u043d\u0441\u0442\u0432\u0430 \u201c\u0434\u0435\u0432\u0430\u0439\u0441\u043e\u0432\u201d   &quot;icons&quot;: [     {       &quot;src&quot;: &quot;.\/icons\/64x64.png&quot;,       &quot;sizes&quot;: &quot;64x64&quot;,       &quot;type&quot;: &quot;image\/png&quot;     },     {       &quot;src&quot;: &quot;.\/icons\/128x128.png&quot;,       &quot;sizes&quot;: &quot;128x128&quot;,       &quot;type&quot;: &quot;image\/png&quot;     },     {       &quot;src&quot;: &quot;.\/icons\/256x256.png&quot;,       &quot;sizes&quot;: &quot;256x256&quot;,       &quot;type&quot;: &quot;image\/png&quot;,       &quot;purpose&quot;: &quot;any maskable&quot;     },     {       &quot;src&quot;: &quot;.\/icons\/512x512.png&quot;,       &quot;sizes&quot;: &quot;512x512&quot;,       &quot;type&quot;: &quot;image\/png&quot;     }   ],   &quot;serviceworker&quot;: {     &quot;src&quot;: &quot;.\/service-worker.js&quot; \/\/ \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u0444\u0430\u0439\u043b \u0441 \u043a\u043e\u0434\u043e\u043c \u0421\u0412   } }<\/code><\/pre>\n<p>  <\/p>\n<p><strong>\u0420\u0443\u0447\u043d\u0430\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0421\u0412, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0449\u0435\u0433\u043e \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u044e &quot;\u0441\u043d\u0430\u0447\u0430\u043b\u0430 \u043a\u044d\u0448&quot;<\/strong><\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">\/\/ \u041d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u043a\u044d\u0448\u0430 \/\/ \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 \/\/ \u0432 \u0434\u0430\u043d\u043d\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435, \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u044c \u0432\u0435\u0440\u0441\u0438\u044e \u043a\u044d\u0448\u0430 - my-cache-v2 const CACHE_NAME = 'my-cache-v1'  \/\/ \u041a\u0440\u0438\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0435 \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0440\u0435\u0441\u0443\u0440\u0441\u044b const ASSETS_TO_CACHE = [   '.\/index.html',   '.\/offline.html',   '.\/style.css',   '.\/script.js' ]  \/\/ \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 \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432, \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u043c\u043e\u0435 \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438 \u0421\u0412 self.addEventListener('install', (e) =&gt; {   e.waitUntil(     caches       .open(CACHE_NAME)       .then((cache) =&gt; cache.addAll(ASSETS_TO_CACHE))   )   self.skipWaiting() })  \/\/ \u0423\u0434\u0430\u043b\u0435\u043d\u0438\u0435 \u0441\u0442\u0430\u0440\u043e\u0433\u043e \u043a\u044d\u0448\u0430 \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u0430\u043a\u0442\u0438\u0432\u0430\u0446\u0438\u0438 \u043d\u043e\u0432\u043e\u0433\u043e \u0421\u0412 self.addEventListener('activate', (e) =&gt; {   e.waitUntil(     caches       .keys()       .then((keys) =&gt;         Promise.all(           keys.map((key) =&gt; {             if (key !== CACHE_NAME) {               return caches.delete(key)             }           })         )       )   )   self.clients.claim() })  \/\/ \u041e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u0441\u0435\u0442\u0435\u0432\u044b\u0445 \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 \/*   1. \u0412\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f \u043f\u043e\u0438\u0441\u043a \u0441\u043e\u0432\u043f\u0430\u0434\u0435\u043d\u0438\u044f   2. \u0415\u0441\u043b\u0438 \u0432 \u043a\u044d\u0448\u0435 \u0438\u043c\u0435\u0435\u0442\u0441\u044f \u043e\u0442\u0432\u0435\u0442, \u043e\u043d \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442\u0441\u044f   3. \u0415\u0441\u043b\u0438 \u043e\u0442\u0432\u0435\u0442\u0430 \u0432 \u043a\u044d\u0448\u0435 \u043d\u0435\u0442, \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f \u0441\u0435\u0442\u0435\u0432\u043e\u0439 \u0437\u0430\u043f\u0440\u043e\u0441   4. \u041e\u0442\u0432\u0435\u0442 \u043d\u0430 \u0441\u0435\u0442\u0435\u0432\u043e\u0439 \u0437\u0430\u043f\u0440\u043e\u0441 \u043a\u044d\u0448\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0438 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442\u0441\u044f   5. \u0412 \u043a\u044d\u0448 \u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u0442\u0432\u0435\u0442\u044b \u043d\u0430 `GET-\u0437\u0430\u043f\u0440\u043e\u0441\u044b`   6. \u041f\u0440\u0438 \u0432\u043e\u0437\u043d\u0438\u043a\u043d\u043e\u0432\u0435\u043d\u0438\u0438 \u043e\u0448\u0438\u0431\u043a\u0438 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442\u0441\u044f \u0440\u0435\u0437\u0435\u0440\u0432\u043d\u0430\u044f \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430 *\/ self.addEventListener('fetch', (e) =&gt; {   e.respondWith(     caches       .match(e.request)       .then((response) =&gt;           response || fetch(e.request)             .then((response) =&gt;               caches.open(CACHE_NAME)                 .then((cache) =&gt; {                   if (e.request.method === 'GET') {                     cache.put(e.request, response.clone())                   }                   return response                 })           )       )       .catch(() =&gt; caches.match('.\/offline.html'))   ) })<\/code><\/pre>\n<p>  <\/p>\n<p><strong>\u041a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044f <code>Webpack<\/code><\/strong><\/p>\n<p>  <\/p>\n<p>\u041f\u0440\u0438\u043c\u0435\u0440 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u0432\u0435\u0431\u043f\u0430\u043a\u0430 \u0434\u043b\u044f \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0439 \u0441\u0431\u043e\u0440\u043a\u0438 \u043f\u0440\u043e\u0433\u0440\u0435\u0441\u0441\u0438\u0432\u043d\u043e\u0433\u043e \u0432\u0435\u0431-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f.<\/p>\n<p>  <\/p>\n<p>\u041f\u0440\u0435\u0434\u043f\u043e\u043b\u043e\u0436\u0438\u043c, \u0447\u0442\u043e \u0432 \u043d\u0430\u0448\u0435\u043c \u043f\u0440\u043e\u0435\u043a\u0442\u0435 \u0438\u043c\u0435\u0435\u0442\u0441\u044f 4 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u0438:<\/p>\n<p>  <\/p>\n<ul>\n<li><code>public<\/code> \u2014 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044f \u0441\u043e \u0441\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u043c\u0438 \u0440\u0435\u0441\u0443\u0440\u0441\u0430\u043c\u0438, \u0432\u043a\u043b\u044e\u0447\u0430\u044f <code>index.html<\/code>, <code>manifest.json<\/code> \u0438 <code>sw-reg.js<\/code><\/li>\n<li><code>src<\/code> \u2014 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044f \u0441 \u043a\u043e\u0434\u043e\u043c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f<\/li>\n<li><code>build<\/code> \u2014 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044f \u0434\u043b\u044f \u0441\u0431\u043e\u0440\u043a\u0438<\/li>\n<li><code>config<\/code> \u2014 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044f \u0441 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430\u043c\u0438, \u0432\u043a\u043b\u044e\u0447\u0430\u044f <code>.env<\/code>, <code>paths.js<\/code> \u0438 <code>webpack.config.js<\/code><\/li>\n<\/ul>\n<p>  <\/p>\n<p>\u0412 \u0444\u0430\u0439\u043b\u0435 <code>public\/sw-reg.js<\/code> \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442\u0441\u044f \u043a\u043e\u0434 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u0438 \u0421\u0412:<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">if ('serviceWorker' in navigator) {   window.addEventListener('load', () =&gt; {     navigator.serviceWorker       .register('.\/service-worker.js')       .then((reg) =&gt; {         console.log('\u0421\u0412 \u0437\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u043d: ', reg)       })       .catch((err) =&gt; {         console.error('\u0420\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u044f \u0421\u0412 \u043f\u0440\u043e\u0432\u0430\u043b\u0438\u043b\u0430\u0441\u044c: ', err)       })   }) }<\/code><\/pre>\n<p>  <\/p>\n<p>\u0412 \u0444\u0430\u0439\u043b\u0435 <code>config\/paths.js<\/code> \u043e\u0441\u0443\u0449\u0435\u0441\u0442\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u044d\u043a\u0441\u043f\u043e\u0440\u0442 \u043f\u0443\u0442\u0435\u0439 \u043a \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044f\u043c \u0441 \u0444\u0430\u0439\u043b\u0430\u043c\u0438 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f:<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">const path = require('path')  module.exports = {   public: path.resolve(__dirname, '..\/public'),   src: path.resolve(__dirname, '..\/src'),   build: path.resolve(__dirname, '..\/build') }<\/code><\/pre>\n<p>  <\/p>\n<p>\u0414\u043e\u043f\u0443\u0441\u0442\u0438\u043c, \u0447\u0442\u043e \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0444\u0440\u043e\u043d\u0442\u0435\u043d\u0434-\u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u0430 \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c <code>React<\/code>, \u0430 \u0442\u0430\u043a\u0436\u0435, \u0447\u0442\u043e \u0432 \u043f\u0440\u043e\u0435\u043a\u0442\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f <code>TypeScript<\/code>. \u0422\u043e\u0433\u0434\u0430 \u0444\u0430\u0439\u043b <code>webpack.config.js<\/code> \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c:<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">const webpack = require('webpack') \/\/ \u0438\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u0443\u0435\u043c \u043f\u0443\u0442\u0438 \u043a \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044f\u043c \u0441 \u0444\u0430\u0439\u043b\u0430\u043c\u0438 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f const paths = require('..\/paths')  \/\/ \u043f\u043b\u0430\u0433\u0438\u043d \u0434\u043b\u044f \u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0441\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432 \u0432 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044e \u0441\u0431\u043e\u0440\u043a\u0438 const CopyWebpackPlugin = require('copy-webpack-plugin') \/\/ \u043f\u043b\u0430\u0433\u0438\u043d \u0434\u043b\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 `index.html` - \u0432\u0441\u0442\u0430\u0432\u043a\u0438 \u0441\u0441\u044b\u043b\u043e\u043a \u043d\u0430 \u0441\u0442\u0438\u043b\u0438 \u0438 \u0441\u043a\u0440\u0438\u043f\u0442\u044b, \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u043c\u0435\u0442\u0430\u0434\u0430\u043d\u043d\u044b\u0445 \u0438 \u0442.\u0434. const HtmlWebpackPlugin = require('html-webpack-plugin') \/\/ \u043f\u043b\u0430\u0433\u0438\u043d \u0434\u043b\u044f \u043e\u0431\u0435\u0441\u043f\u0435\u0447\u0435\u043d\u0438\u044f \u043f\u0440\u044f\u043c\u043e\u0433\u043e \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u043a \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u043c \u0441\u0440\u0435\u0434\u044b \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u044f const Dotenv = require('dotenv-webpack') \/\/ \u043f\u043b\u0430\u0433\u0438\u043d \u0434\u043b\u044f \u043c\u0438\u043d\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 \u0438 \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u044f \u043d\u0435\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u043e\u0433\u043e CSS const MiniCssExtractPlugin = require('mini-css-extract-plugin') \/\/ \u043f\u043b\u0430\u0433\u0438\u043d \u0434\u043b\u044f \u0441\u0436\u0430\u0442\u0438\u044f \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0439 const ImageminPlugin = require('imagemin-webpack-plugin').default \/\/ \u043f\u043b\u0430\u0433\u0438\u043d \u0434\u043b\u044f \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0431\u043b\u043e\u043a\u043e\u0432 \u043a\u043e\u0434\u0430 const AddAssetHtmlPlugin = require('add-asset-html-webpack-plugin')  \/\/ \u041f\u043b\u0430\u0433\u0438\u043d \u0434\u043b\u044f \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u0421\u0412 const { GenerateSW } = require('workbox-webpack-plugin')  \/\/ \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 Babel const babelLoader = {   loader: 'babel-loader',   options: {     presets: ['@babel\/preset-env', '@babel\/preset-react'],     plugins: [       '@babel\/plugin-proposal-class-properties',       '@babel\/plugin-syntax-dynamic-import',       '@babel\/plugin-transform-runtime'     ]   } }  module.exports = {   \/\/ \u0440\u0435\u0436\u0438\u043c \u0441\u0431\u043e\u0440\u043a\u0438   mode: 'production',   \/\/ \u0432\u0445\u043e\u0434\u043d\u0430\u044f \u0442\u043e\u0447\u043a\u0430   entry: {     index: {       import: `${paths.src}\/index.js`,       dependOn: ['react', 'helpers']     },     react: ['react', 'react-dom'],     helpers: ['immer', 'nanoid']   },   \/\/ \u043e\u0442\u043a\u043b\u044e\u0447\u0430\u0435\u043c \u043b\u043e\u0433\u0433\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435   devtool: false,   \/\/ \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0441\u0431\u043e\u0440\u043a\u0438   output: {     \/\/ \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044f \u0441\u0431\u043e\u0440\u043a\u0438     path: paths.build,     \/\/ \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u0444\u0430\u0439\u043b\u0430     filename: 'js\/[name].[contenthash].bundle.js',     publicPath: '.\/',     \/\/ \u043e\u0447\u0438\u0441\u0442\u043a\u0430 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u0438 \u043f\u0440\u0438 \u043a\u0430\u0436\u0434\u043e\u0439 \u0441\u0431\u043e\u0440\u043a\u0435     clean: true,     crossOriginLoading: 'anonymous',     module: true   },   resolve: {     alias: {       '@': `${paths.src}\/components`     },     extensions: ['.mjs', '.js', '.jsx', '.ts', '.tsx', '.json']   },   experiments: {     topLevelAwait: true,     outputModule: true   },   module: {     rules: [       \/\/ JavaScript, React       {         test: \/\\.m?jsx?$\/i,         exclude: \/node_modules\/,         use: babelLoader       },       \/\/ TypeScript       {         test: \/.tsx?$\/i,         exclude: \/node_modules\/,         use: [babelLoader, 'ts-loader']       },       \/\/ CSS, SASS       {         test: \/\\.(c|sa|sc)ss$\/i,         use: [           'style-loader',           {             loader: 'css-loader',             options: { importLoaders: 1 }           },           'sass-loader'         ]       },       \/\/ \u0441\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0435 \u0440\u0435\u0441\u0443\u0440\u0441\u044b - \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0438 \u0448\u0440\u0438\u0444\u0442\u044b       {         test: \/\\.(jpe?g|png|gif|svg|eot|ttf|woff2?)$\/i,         type: 'asset'       },       {         test: \/\\.(c|sa|sc)ss$\/i,         use: [           MiniCssExtractPlugin.loader,           {             loader: 'css-loader',             options: { importLoaders: 1 }           },           'sass-loader'         ]       }     ]   },   plugins: [     new CopyWebpackPlugin({       patterns: [         {           from: `${paths.public}\/assets`         }       ]     }),      new HtmlWebpackPlugin({       template: `${paths.public}\/index.html`     }),      \/\/ \u044d\u0442\u043e \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0438\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0440\u0435\u0430\u043a\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u0434\u0438\u043d \u0440\u0430\u0437     new webpack.ProvidePlugin({       React: 'react'     }),      new Dotenv({       path: '.\/config\/.env'     }),      new MiniCssExtractPlugin({       filename: 'css\/[name].[contenthash].css',       chunkFilename: '[id].css'     }),      new ImageminPlugin({       test: \/\\.(jpe?g|png|gif|svg)$\/i     }),      \/\/ \u0414\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u043a\u043e\u0434 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u0438 \u0421\u0412 \u0432 `index.html`     new AddAssetHtmlPlugin({ filepath: `${paths.public}\/sw-reg.js` }),      \/\/ \u0413\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u043c \u0421\u0412     new GenerateSW({       clientsClaim: true,       skipWaiting: true     })   ],   optimization: {     runtimeChunk: 'single'   },   performance: {     hints: 'warning',     maxEntrypointSize: 512000,     maxAssetSize: 512000   } }<\/code><\/pre>\n<p>  <\/p>\n<p>\u0417\u0434\u0435\u0441\u044c \u0432\u044b \u043d\u0430\u0439\u0434\u0435\u0442\u0435 \u0448\u043f\u0430\u0440\u0433\u0430\u043b\u043a\u0443 \u043f\u043e \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0435 \u0432\u0435\u0431\u043f\u0430\u043a\u0430. \u041f\u0440\u0438\u043c\u0435\u0440 \u043f\u043e\u043b\u043d\u043e\u0439 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438 \u0432\u0435\u0431\u043f\u0430\u043a\u0430 \u0434\u043b\u044f <code>JS\/React\/TS-\u043f\u0440\u043e\u0435\u043a\u0442\u0430<\/code> \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0437\u0434\u0435\u0441\u044c.<\/p>\n<p>  <\/p>\n<p><strong>React PWA<\/strong><\/p>\n<p>  <\/p>\n<p>\u0414\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0433\u043e\u0442\u043e\u0432\u044b\u0439 \u0448\u0430\u0431\u043b\u043e\u043d <code>React-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f<\/code> \u0441 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044f\u043c\u0438 <code>PWA<\/code>, \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u043a\u043e\u043c\u0430\u043d\u0434\u0443:<\/p>\n<p>  <\/p>\n<pre><code class=\"bash\">yarn create react-app my-app --template pwa # \u0438\u043b\u0438 npx create-react-app ...<\/code><\/pre>\n<p>  <\/p>\n<p>\u0418\u043b\u0438, \u0435\u0441\u043b\u0438 \u0440\u0435\u0447\u044c \u0438\u0434\u0435\u0442 \u043e <code>TypeScript-\u043f\u0440\u043e\u0435\u043a\u0442\u0435<\/code>:<\/p>\n<p>  <\/p>\n<pre><code class=\"bash\">yarn create react-app my-app --template pwa-typescript # \u0438\u043b\u0438 npx create-react-app ...<\/code><\/pre>\n<p>  <\/p>\n<p>\u041a\u0440\u043e\u043c\u0435 \u043f\u0440\u043e\u0447\u0435\u0433\u043e, \u0432 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u0438 <code>src<\/code> \u0441\u043e\u0437\u0434\u0430\u044e\u0442\u0441\u044f \u0444\u0430\u0439\u043b\u044b <code>service-worker.ts<\/code> \u0438 <code>serviceWorkerRegister.ts<\/code> (\u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0439 \u0438\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0432 <code>index.tsx<\/code>), \u0430 \u0432 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u0438 <code>public<\/code> \u2014 \u0444\u0430\u0439\u043b <code>manifest.json<\/code>.<\/p>\n<p>  <\/p>\n<p>\u0417\u0430\u0442\u0435\u043c, \u043f\u0435\u0440\u0435\u0434 \u0441\u0431\u043e\u0440\u043a\u043e\u0439 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043a\u043e\u043c\u0430\u043d\u0434\u044b <code>yarn build<\/code> \u0438\u043b\u0438 <code>npm run build<\/code>, \u0432 \u0444\u0430\u0439\u043b <code>src\/index.tsx<\/code> \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0432\u043d\u0435\u0441\u0442\u0438 \u043e\u0434\u043d\u043e \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0435:<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">\/\/ \u0434\u043e serviceWorkerRegistration.unregister();  \/\/ \u043f\u043e\u0441\u043b\u0435 serviceWorkerRegistration.register();<\/code><\/pre>\n<p>  <\/p>\n<p>\u041f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u043e\u0431 \u044d\u0442\u043e\u043c \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u043e\u0447\u0438\u0442\u0430\u0442\u044c <a href=\"https:\/\/create-react-app.dev\/docs\/making-a-progressive-web-app\/\">\u0437\u0434\u0435\u0441\u044c<\/a>.<\/p>\n<p>  <\/p>\n<p><strong>Vue PWA<\/strong><\/p>\n<p>  <\/p>\n<p>\u0421 <code>Vue<\/code> \u0434\u0435\u043b\u0430 \u043e\u0431\u0441\u0442\u043e\u044f\u0442 \u0435\u0449\u0435 \u043f\u0440\u043e\u0449\u0435.<\/p>\n<p>  <\/p>\n<p>\u0413\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u043e \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c <code>vue-cli<\/code>:<\/p>\n<p>  <\/p>\n<pre><code class=\"bash\">yarn global add @vue\/cli # \u0438\u043b\u0438 npm i -g @vue\/cli<\/code><\/pre>\n<p>  <\/p>\n<p>\u0417\u0430\u0442\u0435\u043c, \u043f\u0440\u0438 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0438 \u0448\u0430\u0431\u043b\u043e\u043d\u0430 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043a\u043e\u043c\u0430\u043d\u0434\u044b <code>vue create my-app<\/code>, \u0432\u044b\u0431\u0438\u0440\u0430\u0435\u043c <code>Manually select features<\/code> \u0438 <code>Progressive Web App (PWA) Support<\/code>.<\/p>\n<p>  <\/p>\n<p>\u041a\u0440\u043e\u043c\u0435 \u043f\u0440\u043e\u0447\u0435\u0433\u043e, \u0432 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u0438 <code>src<\/code> \u0441\u043e\u0437\u0434\u0430\u0435\u0442\u0441\u044f \u0444\u0430\u0439\u043b <code>registerServiceWorker.ts<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0438\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0432 <code>main.ts<\/code>. \u0414\u0430\u043d\u043d\u044b\u0439 \u0444\u0430\u0439\u043b \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0441\u0441\u044b\u043b\u043a\u0443 \u043d\u0430 \u0444\u0430\u0439\u043b <code>service-worker.js<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439, \u043a\u0430\u043a \u0438 <code>manifest.json<\/code>, \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0441\u043e\u0437\u0434\u0430\u0435\u0442\u0441\u044f \u043f\u0440\u0438 \u0441\u0431\u043e\u0440\u043a\u0435 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043a\u043e\u043c\u0430\u043d\u0434\u044b <code>yarn build<\/code> \u0438\u043b\u0438 <code>npm run build<\/code>. \u0420\u0430\u0437\u0443\u043c\u0435\u0435\u0442\u0441\u044f, \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0435 \u043e\u0431\u043e\u0438\u0445 \u0444\u0430\u0439\u043b\u043e\u0432 \u043c\u043e\u0436\u043d\u043e <a href=\"https:\/\/cli.vuejs.org\/ru\/core-plugins\/pwa.html\">\u043a\u0430\u0441\u0442\u043e\u043c\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c<\/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\/563724\/\"> https:\/\/habr.com\/ru\/company\/macloud\/blog\/563724\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"\n<div class=\"post__text post__text-html post__text_v1\" id=\"post-content-body\">\n<p><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/q3\/h3\/mw\/q3h3mwmy5zsl-8i3svvhojkmyww.png\" alt=\"image\"><\/p>\n<p>  <\/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<p>\u042d\u0442\u043e \u0432\u0442\u043e\u0440\u0430\u044f \u0447\u0430\u0441\u0442\u044c \u0440\u0443\u043a\u043e\u0432\u043e\u0434\u0441\u0442\u0432\u0430. \u0412\u043e\u0442 \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043f\u0435\u0440\u0432\u0443\u044e \u0447\u0430\u0441\u0442\u044c.<\/p>\n<p>  <\/p>\n<h2 id=\"moduli-predostavlyaemye-wb\">\u041c\u043e\u0434\u0443\u043b\u0438, \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u043c\u044b\u0435 <code>WB<\/code><\/h2>\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-325219","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/325219","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=325219"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/325219\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=325219"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=325219"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=325219"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}