且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

清单start_url未由Service Worker缓存

更新时间:2023-09-09 12:09:10

让我们看看Lighthouse的

Let's look at Lighthouse's source code

static assessOfflineStartUrl(artifacts, result) {
  const hasOfflineStartUrl = artifacts.StartUrl.statusCode === 200;

  if (!hasOfflineStartUrl) {
    result.failures.push('Manifest start_url is not cached by a service worker');
  }

}

我们注意到,它不是检查缓存,而是检查入口点的响应.这样做的原因必须是您的服务人员未在提取时发送适当的响应.

We can notice, that it's not checking your cache, but response of the entry point. The reason for that must be that your service worker is not sending proper Response on fetch.

您将知道它正在运行,如果在DevTools中,在您的第一个请求中,大小列将(来自ServiceWorker):

You'll know that it's working, if in DevTools, in your first request, there'll be (from ServiceWorker) in size column:

您提供的代码有两个问题:

There're two problems with the code you've provided:

第一个是您将服务人员代码与服务人员注册代码弄混了.服务人员注册代码应为您在网页上执行的代码.

First one is that you're messing service worker code with service worker registration code. Service worker registration code should be the code executed on your webpage.

该代码应包含在您的页面上:

That code should be included on your page:

if ('serviceWorker' in navigator) {
  window.addEventListener('load', function() {
    navigator.serviceWorker.register('/worker.js').then(function(registration) {
      console.log('ServiceWorker registration successful with scope: ', registration.scope);
    }, function(err) {
      console.log('ServiceWorker registration failed: ', err);
    });
  });
}

,其余粘贴内容应为worker.js代码.但是,由于已将文件存储在缓存中,因此安装了Service Worker,因此我怀疑您只是错误地粘贴了此文件.

and the rest of what you've pasted should be your worker.js code. However service worker get installed, because you've files in cache, so I suspect you just pasted this incorrectly.

第二个(实际)问题是服务工作者没有返回此缓存的文件.正如我早先所证明的那样,来自灯塔的错误意味着服务工作者没有返回start_url入口文件.

The second (real) problem is that service worker is not returning this cached files. As I've proved earlier, that error from lighthouse means that service worker is not returning start_url entry file.

要实现的最基本的代码是:

The most basic code to achieve that is:

self.addEventListener('fetch', function(event) {
  event.respondWith(caches.match(event.request));
});

Service Worker是事件驱动的,因此当您的页面想要获取某些资源时,Service Worker会做出反应,并从缓存中提供资源.在现实世界中,您确实不希望那样使用它,因为您需要某种后备.我强烈建议您阅读在此处为缓存提供文件

Service worker is event-driven, so when your page wants to get some resource, service worker reacts, and serves the one from cache. In real world, you really don't want to use it like that, because you need some kind of fallback. I strongly recommend reading section Serving files from the cache here

修改:我在以下位置创建了拉动请求 Lighthouse源代码来澄清该错误消息

Edit: I've created pull request in Lighthouse source code to clarify that error message