乐闻世界logo
搜索文章和话题

When and how does a pwa update itself

8 个月前提问
5 个月前修改
浏览次数135

3个答案

1
2
3

在 Progressive Web Application (PWA) 中,Service Worker 是一种运行在浏览器后台的脚本,负责管理缓存以及使应用能够在离线时工作。更新 Service Worker 管理的文件通常遵循以下流程:

文件更新流程:

  1. 安装 Service Worker: 当用户首次访问 PWA 或者 Service Worker 文件 (service-worker.js) 有更新时,浏览器会尝试安装新的 Service Worker。这时,Service Worker 的 install 事件被触发。

  2. 缓存新文件: 在 install 事件的处理函数中,通常会编写代码来打开缓存,并使用 cache.addAll() 方法缓存一个文件列表。此时,可以决定需要缓存哪些新文件或更新的文件。

  3. 激活新的 Service Worker: 安装完成后,新的 Service Worker 会进入 waiting 状态。当网站上没有任何页面使用旧的 Service Worker 时,新的 Service Worker 会接收到 activate 事件。在 activate 事件的处理函数中,通常会清理旧缓存。

  4. 管理旧缓存: 在激活阶段,可以通过比较缓存的版本来决定是否删除旧缓存中的文件,或者是整个旧缓存。这是通过 caches.delete 方法实现的。

  5. 更新完成: 一旦新的 Service Worker 被激活并且旧缓存被清理,新的缓存开始生效,之后的网络请求都将通过新的 Service Worker 来处理。通过这个方式,文件得以更新。

何时更新:

  • Service Worker 文件变更: 每次用户访问 PWA 时,浏览器都会检查 Service Worker 文件是否有变更。如果检测到文件内容有一字节的改动,浏览器会认为 Service Worker 更新了,并开始上述的安装过程。

  • 开发者触发更新: 开发者可以通过更改 Service Worker 文件,例如更新缓存文件的列表、修改缓存策略等来触发更新。开发者也可以通过版本号的方式来控制缓存的更新。

  • 用户清空浏览器缓存: 如果用户清空了浏览器缓存,下次访问时 Service Worker 将会重新安装,意味着文件必须重新缓存。

示例:

在 Service Worker 的安装阶段,一个常见的更新文件的例子如下:

javascript
const CACHE_NAME = 'cache-v1'; const URLS_TO_CACHE = [ '/', '/styles/main.css', '/script/main.js' ]; self.addEventListener('install', (event) => { event.waitUntil( caches.open(CACHE_NAME) .then((cache) => { console.log('Opened cache'); return cache.addAll(URLS_TO_CACHE); }) ); }); self.addEventListener('activate', (event) => { const cacheWhitelist = [CACHE_NAME]; event.waitUntil( caches.keys().then((cacheNames) => { return Promise.all( cacheNames.map((cacheName) => { if (cacheWhitelist.indexOf(cacheName) === -1) { return caches.delete(cacheName); } }) ); }) ); });

在这个示例中,我们定义了一个缓存名称和需要缓存的文件列表。在 install 事件中,我们打开指定的缓存并添加了需要的文件。在 activate 事件中,我们移除了不在白名单中的所有旧缓存。这样,当 Service Worker 文件更新后,新的缓存策略就会生效,旧的文件被更新。

2024年6月29日 12:07 回复

No cache scenario (No Service worker): Your PWA app will be cached only when you use Service worker. Manifest.json will help adding your web app to home screen with a icon and open without address bar. If you don't have a service worker or if your browser don't support it, web page will be loaded fresh every single time. No Cache.

Cache-On Scenario (With Service worker): Assuming you have service workers configured, service workers can cache by lazy loading or prefetching the files that are configured for caching (You can include or exclude caching anything from html, CSS, images to JSON/XML API responses).

After the initial cache, service worker will use the cache to serve your apps network request based on cache approach you have implemented from below ones.

  • cache falling back to network
  • Network falling back to cache
  • Cache then network

Most apps choose to precache due to performance benefits and look for new files on loading, if any changes found will be loaded on next session or prompt user to refresh. With this solution, each file will have a long Hash string for each file cached by service worker. On load of each application, hash code from server will be fetched to match and find what file needs to be updated and the same will be updated in a separate service worker thread. You can notice this in network tab -> service worker response in chrome developer tools.

If you choose network-first approach, you can avoid showing old content on initial load, but loose significant performance benefits that comes with caching.

2024年6月29日 12:07 回复

Only two events…

In essence, there are only two events that will automatically trigger a PWA update:

  1. A change in the linked manifest.json; e.g. a changed icon file or a changed scope or start_url.
  2. A one-character change in the controlling service-worker.js. Hence, if you store the version number in a const in this file and change it, an update of the PWA will be triggered.

When a change is detected, the new version will normally be activated only with the next PWA load. So, in all, two reloads are necessary to see a change.

How the update eventually is handled, is ultimately determined by the service-worker.js. Different update strategies may be defined in terms of the size and volatility of the PWA assets. It is also possible to activate a new service immediately.

However, there is one important caveat. Make sure that the browser cache expiry directive set by the .htaccess file of your asset server is set to a really short duration (e.g. hours) or even to none. Failing to do so, will result in the browser not seeing any change for days to come in the manifest.json nor the service-worker.js.

More details about service worker behaviour are available from Google Web Fundamentals.

2024年6月29日 12:07 回复

你的答案