Service Worker 即时声明页面的最佳实践

2024-03-08

由于应用程序和用户体验的性质,我目前设置了一名服务工作人员来立即认领该页面。

由于此应用程序是从 AppCache 转换过来的,AppCache 为每个用户创建了一个动态清单文件,因此我发现最好的方法是将此清单文件解析为 JSON 数组并将其发送到 Service Worker 以便缓存它。问题是我需要等到 Service Worker 处于活动状态才能接收该数组。

我目前已将该函数的超时设置为 10000(见下文),但成功率不是 100%。Edit:我经常发现 Service Worker 在 10000 超时结束之前没有激活,导致错误:“TypeError: navigator.serviceWorker.controller is null”。

//Get Request - Service Worker Preperation 
setTimeout(function getRequest() {
  console.log("APP: Enetered getRequest() Method");
  $.ajax({
    type : "GET",
    url : "https://ExampleURL/App/" + 
    localStorage.getItem("user") + ".manifest",
    contentType: "text/plain",
    async : false,
    success : function(response) {
        var myArray = listToArray(response, '\n'); 
        send_message_to_sw(myArray);
    },
    error : function(msg) {
        console.log("ERROR: " + msg);
     }
    });
}, 10000);

我的问题是检查服务工作人员是否处于活动状态的最佳实践是什么,或者我应该增加超时时间吗?

我在下面附上了相关的 Service Worker 代码,以防我设置立即索赔的方式出现问题。

// INSTALL
self.addEventListener('install', function(event) {
  console.log('[ServiceWorker] Installed version', version);
  event.waitUntil(
    caches.open(version).then(function(cache) {
        console.log('[ServiceWorker] Cached cachedFiles for', version);

        return cache.addAll(cacheFiles);

    }).then(function() {

      console.log('[ServiceWorker] Skip waiting on install');
      return self.skipWaiting();
    })
  );
});


 //ACTIVATE
 self.addEventListener('activate', function(event) {

  self.clients.matchAll({
    includeUncontrolled: true
  }).then(function(clientList) {
    var urls = clientList.map(function(client) {
      return client.url;
    });
    console.log('[ServiceWorker] Matching clients:', urls.join(', '));
  });

  event.waitUntil(

    caches.keys().then(function(cacheNames) {
      return Promise.all(
        cacheNames.map(function(cacheName) {
          if (cacheName !== version) {
            console.log('[ServiceWorker] Deleting old cache:', cacheName);
            return caches.delete(cacheName);
          }
        })
      );
    }).then(function() {


      console.log('[ServiceWorker] Claiming clients for version', version);
      return self.clients.claim();
    })
  );
});


//RECIEVE DATA FROM JAVASCRIPT FILE
self.addEventListener('message', function(event){
  console.log("SW Received Message: " + event.data);
  var fullArray = [];

  var che = event.data;
  fullArray = che.splice(',');
  console.log("SWChe2: " + fullArray);
  var result = fullArray.slice(1,-1);


  caches.open(version + 'Manifest')
  .then(function(cache) {
    return cache.addAll(result);
 });
});

navigator.serviceWorker.ready https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorkerContainer/ready是一个客户端页面可以等待的承诺,并且当存在范围包含当前页面的活动服务工作者时将解决。

navigator.serviceWorker.ready.then(registration => {
  // Do something, confident that registration corresponds to
  // an active SW's registration.
});

但是……有两件事。

  • 您可以使用 Cache Storage API 添加项目您页面的上下文 https://googlechrome.github.io/samples/service-worker/window-caches/,无需向服务人员发送消息。window.caches.open('my-cache-name')将使您能够访问服务工作人员可以使用的相同缓存。

  • 如果您拥有一组始终可以使用的资源need要缓存,您最好将它们缓存在您的install处理程序。这可确保服务工作线程无法完成安装,除非缓存了所需的文件。您可以使用fetch()在你的里面install处理程序来检索需要预缓存的资源的 JSON 清单,以及 IndexedDB(而不是localStorage,不向服务工作人员公开)来存储当前用户的名称。只要确保如果您走这条路,您就会利用event.waitUntil()来延迟install处理程序完成,直到全套操作成功。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Service Worker 即时声明页面的最佳实践 的相关文章

随机推荐

  • C - 转换为 2 补码

    我决定这样做 翻转数字 0 1 1 0 LSB 加 1 如果进位 则循环直到 array i 0 但我坚持最后一点 我怎么能在条件循环中这么说呢 您正在谈论扩展算术 大多数处理器都有每次加法运算的进位和溢出结果 但 C 不提供对它们的访问
  • AngularJS - 创建服务对象

    我认为这可能更多是关于 javascript 问题 而不是在 Angular 邮件列表中发帖 希望SO社区也能给予更快的回应 我正在尝试将数据封装在服务中并注入到控制器中 angular module myApp services ngRe
  • C++ 多线程服务器帮助

    我正在使用 boost asio 在 C 中开发多线程服务器 目前我遇到的一个设计问题涉及擦除连接 我有一个服务器实例 其中包含连接对象向量 这些连接接收我解析的命令 其中一个命令专门处理向我的向量中的所有连接发送数据 现在 当连接断开时
  • Google Sheets API:设置权限

    在我的 Java 应用程序中 我正在创建新的 Google 表格 如下所示 Sheets service new Sheets Builder GoogleNetHttpTransport newTrustedTransport JSON
  • 关闭 Windows Mobile 上的 GPRS 连接

    是否有可能在 Windows Mobile 上获取所有打开或缓存的 gprs 连接并以编程方式强制它们关闭 我一直在查看连接管理器 api 但似乎找不到执行此操作的方法 Regards Tony 连接管理器 http msdn micros
  • iOS 分发证书即将到期。我有什么选择?

    我当前的分销证书今天过期了 这意味着我的 AdHoc 和 AppStore 配置文件也都过期了 我有 2 个应用程序已经提交给 Apple 审核 1个正在等待审核 另一个正在 审核中 我似乎无法生成新的分发证书 因为没有选项 只能撤销或下载
  • 如何在基于文档的 macOS 应用程序中处理不同的文档类型?

    如何在一个 macOS 文档应用程序中处理两种不同的自定义文档类型 从 macOS Document App 模板开始 我定义了两种类型 它们也注册在 info plist 中 extension UTType static var tes
  • nhibernate,无法解析属性 QueryOver 仅一张表

    我发现了十几个与我类似的问题 但没有一个能解决我的问题 先感谢您 Ok 我有这门课 public class User IEntity private int id public virtual int Id get return id p
  • iPhone 中的 Twitter 集成无需登录即可阅读公共推文/HashTags?

    大家好 我正在开发一个应用程序 它使用 twitter api 来获取客户的公共推文 他们的标签 目前我正在使用 MGTwitterEngine 它要求用户名 密码来获取推文 我们是否可以通过其他方式在无需登录的情况下获取公共推文及其主题标
  • 逗号分隔列表中值范围的正则表达式

    我想编写一个与数值列表匹配的正则表达式 以逗号分隔的列表给出 允许范围 不允许为空 类似 1 10 20 56 8 7 到目前为止我有 0 9 0 9 0 9 0 9 这完成了大部分工作 除了它只错过了一个范围的情况 例如 1 10 不会验
  • 如何将名称应用于环境?

    全球环境似乎有这个名字R GlobalEnv environment
  • 随机选择矩阵列

    我有一个m x n矩阵 我想在 MATLAB 中的一些神经网络应用程序中使用它 例如 A 24 22 35 40 30 32 42 47 45 39 14 1 10 5 9 2 8 4 1 8 我想随机训练一些列并测试其他剩余的列 因此 第
  • 尝试 rake db:migrate 时未在 Rails 项目中选择数据库

    使用 Rails 应用程序 遇到某种奇怪的数据库 rake 问题 当我执行时 rake db migrate 我收到以下错误 Mysql2 Error No database selected SHOW TABLES See full tr
  • Java中抛出匿名异常

    在 Java 中 即使只是在抛出时声明了异常 也有可能抛出任何异常 如下例 import org springframework dao DataAccessException DataAccessException is abstract
  • AChartEngine,单击时获取绘图值

    我使用 achartengine 编写了一个简单的时间表 我想要做的是通过单击图表上的点来获取已经绘制的值 这可能吗 假设 mChartView 是您的 GraphicalView mChartView setOnClickListener
  • XSL,使用 XML 作为模板的参数

    是否可以通过参数将 XML 传递到 XSL 模板 例如 下面我有模板body调用模板test1通过参数传递一些 XMLvar1 然后我尝试走到节点a使用 XPATH
  • Log4Net 多个记录器

    首先 我在其他主题中看到了很多答案和提示 最相似的是 Log4Net 多个记录器 https stackoverflow com questions 3470272 log4net multiple loggers 3513417 3513
  • xcode 在模拟器和设备上安装速度很慢

    在模拟器上 构建并运行 大约需要 30 秒 在设备上 构建并运行 大约需要 5 分钟 我 99 确信原因是我有很多图像 4000 80mb 构建本身阶段大约需要 2 秒 所以问题在于安装 有人有任何加快速度的建议吗 图像不需要改变 那么是否
  • C Linux:全局变量作为单例位于共享库中

    如果共享库 so 被多个进程使用 是否可以将位于共享库 so 中的全局变量用作单例 例如 初始值为 0 进程 1 递增 var 然后 proc2 递增 val 并打印它 到目前为止 我的实验表明 两个进程都保留变量的副本 如果第一个进程递增
  • Service Worker 即时声明页面的最佳实践

    由于应用程序和用户体验的性质 我目前设置了一名服务工作人员来立即认领该页面 由于此应用程序是从 AppCache 转换过来的 AppCache 为每个用户创建了一个动态清单文件 因此我发现最好的方法是将此清单文件解析为 JSON 数组并将其