Service worker очистить кэш
You can use the materials linked to from this page, but some of the content may be out of date.
We're still working on updating written materials, but check out our new codelabs and videos.
Using the Cache API
Here we cover the Cache API properties and methods.
Обновление Service Worker
Если мы внесем изменения в файл скрипта Service Worker, то браузер будет считать его новым Service Worker, и будет запущено новое событие установки.
Когда мы обновляем Service Worker, новый Service Worker не контролирует клиенты, потому что клиентов обрабатывает старый Service Worker. Когда мы закрываем браузер, старый Service Worker уничтожается, а новый заменяет старый Service Worker.
Если мы хотим использовать нового Service Worker, как только установка будет завершена, мы можем использовать метод self.skipWaiting().
Этот метод активирует Service Worker после завершения установки. Если новый Service Worker не удается установить, клиентов (страницы) продолжает обрабатывать старый. В режиме разработки установите флажок обновления при перезагрузке, тогда Service Worker будет обновляться при обновлении страницы.
Serving files from the cache
To serve content from the cache and make your app available offline you need to intercept network requests and respond with files stored in the cache. There are several approaches to this:
- cache only
- network only
- cache falling back to network
- network falling back to cache
- cache then network
There are a few approaches we don't cover here. See Jake Archibald's Offline Cookbook for a full list.
Cache only
You don't often need to handle this case specifically. Cache falling back to network is more often the appropriate approach.
This approach is good for any static assets that are part of your app's main code (part of that "version" of your app). You should have cached these in the install event, so you can depend on them being there.
If a match isn't found in the cache, the response will look like a connection error.
Network only
This is the correct approach for things that can't be performed offline, such as analytics pings and non-GET requests. Again, you don't often need to handle this case specifically and the cache falling back to network approach will often be more appropriate.
Alternatively, simply don't call event.respondWith , which will result in default browser behaviour.
Cache falling back to the network
If you're making your app offline-first, this is how you'll handle the majority of requests. Other patterns will be exceptions based on the incoming request.
This gives you the "Cache only" behavior for things in the cache and the "Network only" behaviour for anything not cached (which includes all non-GET requests, as they cannot be cached).
Network falling back to the cache
This is a good approach for resources that update frequently, and are not part of the "version" of the site (for example, articles, avatars, social media timelines, game leader boards). Handling network requests this way means the online users get the most up-to-date content, and offline users get an older cached version.
However, this method has flaws. If the user has an intermittent or slow connection they'll have to wait for the network to fail before they get content from the cache. This can take an extremely long time and is a frustrating user experience. See the next approach, Cache then network, for a better solution.
Here we first send the request to the network using fetch() , and only if it fails do we look for a response in the cache.
Cache then network
This is also a good approach for resources that update frequently. This approach will get content on screen as fast as possible, but still display up-to-date content once it arrives.
This requires the page to make two requests: one to the cache, and one to the network. The idea is to show the cached data first, then update the page when/if the network data arrives.
Here is the code in the page:
We are sending a request to the network and the cache. The cache will most likely respond first and, if the network data has not already been received, we update the page with the data in the response. When the network responds we update the page again with the latest information.
Here is the code in the service worker:
This caches the network responses as they are fetched.
Sometimes you can replace the current data when new data arrives (for example, game leaderboard), but be careful not to hide or replace something the user may be interacting with. For example, if you load a page of blog posts from the cache and then add new posts to the top of the page as they are fetched from the network, you might consider adjusting the scroll position so the user is uninterrupted. This can be a good solution if your app layout is fairly linear.
Generic fallback
If you fail to serve something from the cache and/or network you may want to provide a generic fallback. This technique is ideal for secondary imagery such as avatars, failed POST requests, "Unavailable while offline" page.
The item you fallback to is likely to be an install dependency.
You can also provide different fallbacks based on the network error:
Network response errors do not throw an error in the fetch promise. Instead, fetch returns the response object containing the error code of the network error. This means we handle network errors in a .then instead of a .catch .
Стратегии кэширования Service Workers
Существуют способы или стратегии, которые мы можем использовать в Service Workers для реагирования на «выборочные» события. Эти стратегии определяют, как Service Worker будет отвечать на событие fetch в зависимости от типа запроса события.
1. Stale-While-Revalidate
Эта стратегия проверяет ответ в кеше. Если он доступен, то доставляется, и кэш повторно проверяется. Если он недоступен, service worker получает ответ из сети и кэширует его. Давайте рассмотрим код:
Вариант 1
Используем куки. Будем записывать в куки пользователя время его последнего посещения. При следующем заходе сравниваем на сервере его со временем модификации отслеживаемых файлов, и передаем список измененных с того момента файлов в html коде страницы, непосредственно перед регистрацией сервис воркера. Для этого инклюдим туда вывод вот такого php файла:
$files — массив отслеживаемых ресурсов. Для каждого измененного файла будет сгенерирован script таг с ключевым словом /update-resource, что повлечет за собой запрос в сервис воркер.
Там мы фильтруем эти запросы по ключевому слову и загружаем ресурсы заново.
Вот и все, ресурсы обновляются по мере изменения. Однако есть слабые места: куки могут пропадать, и тогда пользователю придется загружать все файлы заново. Так же есть вероятность, что после установки пользователю куки он по каким-то причинам не сможет загрузить все обновленные файлы. В этом случае у него будет «битое» приложение. Попробуем придумать что-то понадежней.
Вариант 2
Будем, как и ребята из Google, передавать отслеживаемые файлы в sw.js, и сверять изменения на стороне клиента. В качестве функционала меры не изобретая хэш-велосипеда возьмем E-Tag или Last-Modified заголовки респонзов — они прекрасно сохраняются в кэше воркера. Правильней взять E-Tag, но чтобы получить его на стороне сервера необходимо будет выполнить локальный запрос к веб-серверу, что немного накладно, а Last-Modified прекрасно вычисляется с помощью filemtime().
Итак, вместо sw.js регистрируем теперь sw.php со следующим кодом:
Он генерирует в начале sw.js объявление ассоциативного массива, инициализированного парами наших отслеживаемых ресурсов.
Дальше при каждом запросе клиентом ресурса в случае попадания url в массив updated сверяем с тем, что у нас в кэше.
Пятнадцать строчек кода, и можно спокойно выкладывать на сервер файлы, и они будут сам обновляться в кэше клиентов.
Единственный оставшийся момент — после загрузки ресурса необходимо будет обновить updated[url.pathname] новым response.headers.get(«Last-Modified») — есть вероятность, что этот файл после последнего получения sw.php был еще раз обновлен, тогда получится несовпадение хидера времени последнего изменения, и это файл будет постоянно обновляться при запросе.
Creating the cache
An origin can have multiple named Cache objects. To create a cache or open a connection to an existing cache we use the caches.open method.
This returns a promise that resolves to the cache object. caches.open accepts a string that will be the name of the cache.
2 Answers 2
My own Service Worker cache is found at the folder:
C:\Users\USER-NAME\AppData\Local\Microsoft\Edge\User Data\Default\Service Worker\CacheStorage\3cedfb74d44f2e84198d23075aef16c34a668ceb .
I have tried to clean it up using in edge://settings/clearBrowserData the option of "Cached images and files", but this didn't touch the Service Worker cache.
So I just went into the above folder with explorer and deleted all its contents, but left the folder itself in place.
Then I started Microsoft Edge, and it started without any problem. It also re-populated the folder with new content.
So my answer is: Yes, you can delete it from Explorer.
If you are worried about safety, you may at first step move the contents to a temporary folder and run Microsoft Edge. If everything works well, you may then delete the temporary folder.
Note: Google Chrome behaves in exactly the same way. Its cache is found at:
C:\Users\USER-NAME\AppData\Local\Google\Chrome\User Data\Default\Service Worker .
Tip: you can just put this into address bar or Run dialog (Windows + R): %appdata%\..\Local\Microsoft\Edge\User Data\Default\Service Worker\CacheStorage . You don't have to worry about username.
@LukeVo awesome tip can be simplified further by using %LocalAppData% instead of %appdata%\..\Local (in some configurations it can be different locations and then %LocalAppData% is the more correct one)
Tried with Google Chrome on Linux, worked fine and websites work just like before. I wonder why the ServiceWorker cache is not in Chrome's cache folder
@harrymc has answered how to brute-flush your cache. Here's a method to go website-by-website, understanding a bit more about what's going on.
Ìf you insert [chrome/edge/vivaldi/. ]://serviceworker-internals/ into the address bar, you can see all registered service workers. However, unregistering them thorugh that page won't clear the cache, as this comprehensive article on love2dev notes.
Note that the service worker will restart as soon as you navigate to that site again.
If you wish to choose which applications can install a service worker on your system, follow the steps described in this article, using the uBlock plugin.
It's a wild guess, but 5GB of ServiceWorker storage is probably some webmail client with offline content enabled: it is fundamental to understand that serviceworkers were initially conceived for mobile devices who are not always online, and thus will cache some web-application data on the local system. Also, a serviceworker can receive push messages for an inactive webapp, and wake up that app. Gmail is a prime example: on mobile, you can read & write email while offline, and it will sync as soon as you go online. And even if the gmail app is not active after a phone restart, the serviceworker will receive the push message that you have something new in your inbox.
As such, on a PC which is always connected to internet, serviceworkers are not really necessary, except maybe to speed up the experience on some websites. It could however be that nowadays some websites simply won't work correctly if you block their serviceworker (but I'd say that's bad coding practice).
For a more comprehensive understanding, read the two linked articles. Also, Googles Introduction to Service Workers can shed some more light on what's going on.
Service Workes как технология для создания offline приложений очень хорошо подходит для кэширования различных ресурсов. Разнообразные тактики работы в сервис воркере с локальным кэшем подробно описаны в Интернете.
Не описано одного — каким образом обновлять файлы в кэше. Единственное, что предлагает Google и MDN, это делать несколько кэшей для разных типов ресурсов, и, когда нужно, изменять в скрипте сервис воркера sw.js версию этого кэша, после чего тот весь удалится.
Другими словами, если у вас, например, десять js файлов, и вы изменили один из них, всем пользователям придется перегружать все js файлы. Достаточно топорная работа.
Из сторонних продуктов (хотя и от Google разработчиков) самой близкой к решению задачи обновления файлов кэша сервис воркера является sw-precache библиотека. Она добавляет в sw.js хэши всех файлов, отслеживание изменений которых задано разработчиком. При изменении на сервере хоть одного из них при следующей активации сервис воркера опять обновляется весь кэш у клиента, — но теперь уже без специальных телодвижений программиста. Топор заменили колуном.
Как добавить Service Worker
После успешной регистрации Service Worker может выполняться установка. Установка Service Worker:
Если Service Worker новый или обновленный, начнется процесс установки. На этом этапе вы можете кэшировать статический контент или файл.
Это событие срабатывает только в том случае, если «ServiceWorker.js» не существует или файл более новой версии (обновлен).
Service Worker не устанавливается, если какой-либо файл не удалось перехватить, что предусмотрено функцией cache.addAll().
С помощью event.waitUntil() Service Worker не завершает работу, пока промис, переданный методу waitUntil(), не будет разрешен или отклонено. После успешной установки запускается событие активации Service Worker.
Как работает Service Worker
Он перехватывает сетевые запросы, кэширует или извлекает ресурсы из кэша, а также доставляет push-уведомления. К Service Worker может одновременно обращаться множество вкладок в браузере, поскольку только один Service Worker может существовать в каждой области, а его существование не зависит от основного потока.
Чтобы установить Service Worker в проекте, сначала необходимо зарегистрировать Service Worker.
Чтобы зарегистрировать Service Worker, нам нужно проверить, поддерживает ли его браузер, используя Объект navigator. Объект navigator содержит информацию о браузере. Ваш первый Service Worker загружается, когда вы вызываете функцию register().
JavaScript. Быстрый старт
Изучите основы JavaScript на практическом примере по созданию веб-приложения
Service Worker может получить доступ только к папкам, расположенным ниже, поэтому, вероятно, лучше хранить его в корне проекта (самая верхняя папка).
Функция регистрации Service Worker загружает скрипт Service Worker с предоставленного URL-адреса и выполняет его.
В приведенном выше коде ответ содержит информацию о состоянии Service Worker, а также о его объеме. В файле ServiceWorker.js мы можем написать код для установки, обновления, отправки и т. д.
Если Service Worker не удается зарегистрировать, промис регистрации отклоняется, и Service Worker отбрасывается.
Выводы
Нужно помнить о цикле жизни sw.js/sw.php. Этот файл подчиняется правилам стандартного кэширования браузера за одним исключением — живет он на клиенте не больше 24 часов, затем будет принудительно перезагружен при очередной регистрации сервис воркера. С sw.php у нас почти гарантированно всегда будет свежая версия.
Если не хочется влазить в генерацию sw.js, можно скачивать список отслеживаемых ресурсов с Last-Modified с сервера в блоке activate — это, наверное, более правильный способ, но ценой одного лишнего запроса на сервер. А можно как в варианте 1 врезаться в код html страницы, сформировать там ajax запрос с json данными в сервис воркер, где его и обработать, проведя инициализацию массива updated — это, возможно, самый оптимальный и динамичный вариант, он позволит при желании обновлять ресурсы кэша без переустановки сервис воркера.
В качестве дальнейшего развития данной схемы не составит проблем каждому отслеживаемому ресурсу добавить декларативную возможность загружаться отложено — сперва возврат клиенту из кэша, затем загрузка из сети для последующих показов.
Еще один пример приложения — картинки с различным размером (srcset или программная установка). При загрузке такого ресурса можно сперва в кэше поискать изображение бОльшего разрешения, сэкономив тем самым запрос на сервер. Или использовать картинку меньшего размера на время загрузки основной.
Из общих кэширующих техник также интересна преждевременная загрузка: допустим, известно, что в следующем релизе приложения появятся дополнительные ресурсы — новый шрифт или тяжелая картинка, например. Можно ее загрузить в кэш заранее по событию load — когда у пользователя откроется полностью страница и он начнет ее читать. Это будет незаметно и эффективно.
Напоследок пример рабочего sw.js (работает в связке с вышеуказанным sw.php) с несколькими кэшами (в том числе с кэшированием сгенерированных php скриптом картинок) и реализованным прозрачным обновлением кэша по второму варианту.
Service Worker — это файл скрипта Java, который запускается в браузере пользователя как фоновый процесс.
Working with data
The Cache API comes with several methods that let us create and manipulate data in the cache. These can be grouped into methods that either create, match, or delete data.
Create data
There are three methods we can use to add data to the cache. These are add , addAll , and put . In practice, we will call these methods on the cache object returned from caches.open() . For example:
Caches.open returns the example-cache Cache object, which is passed to the callback in .then . We call the add method on this object to add the file to that cache.
cache.add(request) - The add method takes a URL, retrieves it, and adds the resulting response object to the given cache. The key for that object will be the request, so we can retrieve this response object again later by this request.
cache.addAll(requests) - This method is the same as add except it takes an array of URLs and adds them to the cache. If any of the files fail to be added to the cache, the whole operation will fail and none of the files will be added.
cache.put(request, response) - This method takes both the request and response object and adds them to the cache. This lets you manually insert the response object. Often, you will just want to fetch() one or more requests and then add the result straight to your cache. In such cases you are better off just using cache.add or cache.addAll , as they are shorthand functions for one or more of these operations:
Match data
There are a couple of methods to search for specific content in the cache: match and matchAll . These can be called on the caches object to search through all of the existing caches, or on a specific cache returned from caches.open() .
caches.match(request, options) - This method returns a Promise that resolves to the response object associated with the first matching request in the cache or caches. It returns undefined if no match is found. The first parameter is the request, and the second is an optional list of options to refine the search. Here are the options as defined by MDN:
caches.matchAll(request, options) - This method is the same as .match except that it returns all of the matching responses from the cache instead of just the first. For example, if your app has cached some images contained in an image folder, we could return all images and perform some operation on them like this:
Delete data
We can delete items in the cache with cache.delete(request, options) . This method finds the item in the cache matching the request, deletes it, and returns a Promise that resolves to true . If it doesn't find the item, it resolves to false. It also has the same optional options parameter available to it as the match method.
Retrieve keys
Finally, we can get a list of cache keys using cache.keys(request, options) . This returns a Promise that resolves to an array of cache keys. These will be returned in the same order they were inserted into the cache. Both parameters are optional. If nothing is passed, cache.keys returns all of the requests in the cache. If a request is passed, it returns all of the matching requests from the cache. The options are the same as those in the previous methods.
The keys method can also be called on the caches entry point to return the keys for the caches themselves. This lets you purge outdated caches in one go.
Как очистить кэш Service Worker
В случае активации мы можем удалить существующий кэшированный элемент с помощью метода cache.delete().
Метод caches.keys() предоставляет имена всех доступных кэшей. Каждый раз, когда пользователь делает запрос на странице, запускаются события кэширования Service Worker. В этом случае мы решаем, хотим ли мы, чтобы этот запрос был передан в сеть или был представлен элемент из кэша.
JavaScript. Быстрый старт
Изучите основы JavaScript на практическом примере по созданию веб-приложения
Предоставляем ответ с помощью сетевого вызова.
Метод responseWith() позволяет вам предоставить промис на Response самостоятельно.
Постановка задачи
Нам нужно прозрачное и надежное обновление файлов кэша сервис воркера. Это означает, что разработчик выкладывает измененные файлы на сервер, и у пользователя только они автоматически обновляются при следующем заходе/запросе. Попробуем решить эту задачу.
Возьмем распространенный гугловский пример сервис воркера, работающий по принципу: «сперва из кэша, если там нет — из сети».
Для начала понятно, что нужно иметь список отслеживаемых файлов. Так же, нужно как-то сравнивать их с версиями файлов в кэше. Это можно делать или на сервере, или на клиенте.
Using the Cache API in the service worker
The Service Worker API comes with a Cache interface, that lets you create stores of responses keyed by request. While this interface was intended for service workers it is actually exposed on the window, and can be accessed from anywhere in your scripts. The entry point is caches .
You are responsible for implementing how your script (service worker) handles updates to the cache. All updates to items in the cache must be explicitly requested; items will not expire and must be deleted. However, if the amount of cached data exceeds the browser's storage limit, the browser will begin evicting all data associated with an origin, one origin at a time, until the storage amount goes under the limit again. See Browser storage limits and eviction criteria for more information.
Removing outdated caches
Once a new service worker has installed and a previous version isn't being used, the new one activates, and you get an activate event. Because the old version is out of the way, it's a good time to delete unused caches.
During activation, other events such as fetch are put into a queue, so a long activation could potentially block page loads. Keep your activation as lean as possible, only using it for things you couldn't do while the old version was active.
Further reading
Learn about the Cache API
Learn about using service workers
Except as otherwise noted, the content of this page is licensed under the Creative Commons Attribution 4.0 License, and code samples are licensed under the Apache 2.0 License. For details, see the Google Developers Site Policies. Java is a registered trademark of Oracle and/or its affiliates.
Note that this is NOT the Cache folder. It's the Cache of Service Worker, the path should be AppData\Local\Microsoft\Edge\User Data\Default\Service Worker .
Recently I noticed my hard drive is almost full so I want to clean it up. I noticed the while the Cache folder is acceptable (200MB), the cache of Service Worker folder is so big (> 1GB). I tried unregister all the service workers but the cache folder is still there.
Can I safely just delete them from Windows Explorer?
P.s: as a developer, I am amazed by the amount of registered service workers. Most of them are trackers and useless stuff I should have removed before.
I have read this article but it didn't work for me because:
I can't just go to each website to delete individual Service Worker cache.
Hi sorry I forgot to mention that yes I have read that article. I will update the question. And no, it doesn't work for me.
Checking for support
We can check if the browser supports the Cache API like this:
Storing resources
In this section, we outline a few common patterns for caching resources: on service worker install , on user interaction , and on network response . There are a few patterns we don't cover here. See the Offline Cookbook for a more complete list.
On install - caching the application shell
We can cache the HTML, CSS, JS, and any static files that make up the application shell in the install event of the service worker:
This event listener triggers when the service worker is first installed.
event.waitUntil extends the lifetime of the install event until the passed promise resolves successfully. If the promise rejects, the installation is considered a failure and this service worker is abandoned (if an older version is running, it stays active).
cache.addAll will reject if any of the resources fail to cache. This means the service worker will only install if all of the resources in cache.addAll have been cached.
On user interaction
If the whole site can't be taken offline, you can let the user select the content they want available offline (for example, a video, article, or photo gallery).
One method is to give the user a "Read later" or "Save for offline" button. When it's clicked, fetch what you need from the network and put it in the cache:
In the above example, when the user clicks an element with the cache-article class, we are getting the article ID, fetching the article with that ID, and adding the article to the cache.
On network response
If a request doesn't match anything in the cache, get it from the network, send it to the page and add it to the cache at the same time.
This approach works best for resources that frequently update, such as a user's inbox or article contents. This is also useful for non-essential content such as avatars, but care is needed. If you do this for a range of URLs, be careful not to bloat the storage of your origin — if the user needs to reclaim disk space you don't want to be the prime candidate. Make sure you get rid of items in the cache you don't need any more.
Отладка Service Worker
Как проверить Service Worker на localhost:
От автора: Service Worker — это скрипт, который браузер запускает в фоновом режиме, отдельно от веб-страницы, открывая доступ к функциям, которые не требуют взаимодействия с веб-страницей или с пользователем. Сегодня они уже включают такие функции, как push-уведомления и фоновая синхронизация. В будущем Service Worker могут поддерживать другие вещи, такие как периодическая синхронизация или геозоны.
В этом посте я остановлюсь на еще одной замечательной функции для Service Worker — перехвате и кэшировании сетевых запросов.
Кэширование — одна из самых захватывающих особенностей ПО. Это позволяет нам предоставлять пользователям отзывчивый и стабильный опыт работы с приложениями. Веб-приложение может отображать некоторый контент и выполнять некоторые функции в плохих условиях сети и даже когда пользователь полностью офф-лайн.
Мы рассмотрим пять различных стратегий кэширования. И как и когда вы должны реализовать каждый из них.
JavaScript. Быстрый старт
Изучите основы JavaScript на практическом примере по созданию веб-приложения
Сначала кеш, потом сеть
Сначала сеть, затем кэш
Я рассмотрю каждую стратегию с примерами, чтобы помочь вам лучше понять ее. Вы также узнаете, когда и где их применять в PWA, и какие ресурсы вы можете использовать с ними.
Совет: Используйте Bit (Github) для совместного использования, документирования и управления повторно используемыми компонентами React из разных проектов. Это отличный способ улучшить повторное использование кода, ускорить разработку и создавать масштабируемые приложения.
Читайте также: