在项目中使用Service Worker 与 PWA

news2024/12/23 10:24:58

在这里插入图片描述

小册

这是我整理的学习资料,非常系统和完善,欢迎一起学习

  • 现代JavaScript高级小册

  • 深入浅出Dart

  • 现代TypeScript高级小册

  • linwu的算法笔记📒

引言

最近next项目有使用pwa技术,使用起来也不复杂,目前浏览器的兼容性也比较良好

Service Worker是浏览器中独立于网页运行的脚本,而PWA(渐进式Web应用程序)是一种Web应用程序,其外观和感觉类似于原生应用程序。在讨论Service Worker与PWA之前,让我们先简要了解一下Web Worker。

Web Worker

1. 什么是 Web Worker?

Web Worker 是浏览器内置的线程,用于执行非阻塞事件循环的 JavaScript 代码。由于 JavaScript 是单线程语言,一次只能处理一个任务。复杂任务的出现可能导致主线程被阻塞,严重影响用户体验。Web Worker 的作用是允许主线程创建 worker 线程,使它们可以同时运行。Worker 线程主要负责处理复杂的计算任务,然后将结果返回给主线程。简而言之,worker 线程执行复杂计算,同时保持页面(主线程)的流畅性,不会造成阻塞。

2. 类型

Web Worker 有三种主要类型:

  1. Dedicated Workers【专用 Worker】由主线程实例化,只能与主线程通信。

  2. Shared Workers【共享 Worker】可以被同源的所有线程访问。

  3. Service Workers【服务 Worker】能够控制其关联的网页,拦截和修改导航、资源请求,并缓存资源,使您能够在某些情况下灵活控制应用程序的行为。

3. 限制

1. 同源限制

分配给 Worker 线程运行的脚本文件必须与主线程的脚本文件同源,通常都应该放在同一项目下。

2. DOM 限制

Web Workers 无法访问某些关键的 JavaScript 特性,包括:

1 DOM(因为这可能导致线程不安全)

2 window 对象

3 document 对象

4 parent 对象

3. 文件限制

出于安全考虑,worker 线程无法读取本地文件。它们加载的脚本必须来自网络,并且必须与主线程的脚本同源。

什是Service Worker?

Service Worker(服务工作线程)是一种在浏览器背后运行的脚本,用于提供强大的离线和缓存功能,以改善 Web 应用程序的性能和可靠性。它是渐进式网络应用程序(Progressive Web App,PWA)的关键组成部分,可以让 Web 应用程序更像本地应用程序,即使在离线状态下也能正常工作。Service Worker 是 Web 开发中的一个强大工具,它使开发人员能够更好地控制和管理 Web 页面的资源缓存、网络请求和响应,从而提供更快速、更稳定的用户体验。

image.png

Service Worker 的功能和优点

Service Worker 提供了许多重要功能和优点,其中包括:

1. 离线支持

Service Worker 可以缓存 Web 应用程序的资源,使其在断网或低网络质量环境下仍能够加载和运行。这意味着用户可以随时访问应用程序,无需依赖网络连接。

2. 更快的加载速度

通过将资源缓存在本地,Service Worker 可以显著提高 Web 页面的加载速度。它可以从缓存中获取资源,而无需每次都从服务器重新下载。

3. 支持后台同步

Service Worker 允许在后台执行任务,例如数据同步或推送通知。这使得应用程序可以在不干扰用户的情况下执行一些重要的操作。

4. 增强的安全性

Service Worker 受同源策略的限制,因此它可以提供更安全的资源缓存和请求处理。它还可以用于拦截和处理恶意请求。

5. 支持推送通知

Service Worker 具有推送通知功能,可以通过浏览器向用户发送实时通知,提高用户参与度和留存率。

使用

// 注册 Service Worker
if ('serviceWorker' in navigator) {
  navigator.serviceWorker.register('/sw.js')
    .then(function(registration) {
      console.log('Service Worker 注册成功:', registration);
    })
    .catch(function(error) {
      console.log('Service Worker 注册失败:', error);
    });
}

// 在 Service Worker 中缓存资源
self.addEventListener('install', function(event) {
  event.waitUntil(
    caches.open('my-cache').then(function(cache) {
      return cache.addAll([
        '/',
        '/index.html',
        '/styles.css',
        '/script.js'
      ]);
    })
  );
});

// 拦截网络请求并从缓存中返回资源
self.addEventListener('fetch', function(event) {
  event.respondWith(
    caches.match(event.request).then(function(response) {
      return response || fetch(event.request);
    })
  );
});

我们首先尝试在浏览器中注册一个 Service Worker,并指定了要缓存的资源。然后,在 Service Worker 中,我们通过监听 install 事件来缓存这些资源,并在 fetch 事件中拦截网络请求,从缓存中返回资源。这样,即使在离线时,页面仍能够加载所需资源。

生命周期

Service Worker 的生命周期与 web 页面完全分离。它包括以下几个阶段:

image.png

  • 下载
  • 安装
  • 激活

1.下载

用户首次访问service worker控制的网站或页面时,service worker会立刻被下载。浏览器会下载包含 Service Worker 的 .js 文件。

2.安装

需要在网页进行注册来安装,安装前需要检查是否支持 serviceWorker,如果支持,每次页面加载时就调用 register(),浏览器将会判断是否已注册。 register() 方法的一个重要细节是 Service Worker 文件的位置。在本例中,可以看到 Service Worker 文件位于域的根目录,这意味着 Service Worker 范围将是这个域下的。换句话说,这个 Service Worker 将为这个域中的所有内容接收 fetch 事件。如果我们在 /example/sw/sw.js 注册 Service Worker 文件,那么 Service Worker 只会看到以 /example/ 开头的页面的 fetch 事件(例如 /example/page1/、/example/page2/)。

if ('serviceWorker' in navigator) {
  window.addEventListener('load', function() {
    navigator.serviceWorker.register('/sw/sw.js').then(function(registration) {
      // 注册成功
      console.log('ServiceWorker registration successful with scope: ', registration.scope);
    }, function(err) {
      // 注册失败
      console.log('ServiceWorker registration failed: ', err);
    });
  });
}

注册成功后,install 事件会被触发,将会调用caches.open() 和我们想要的缓存名称, 之后调用 cache.addAll() 并传入文件数组。 这是一个promise 链( caches.open() 和 cache.addAll() )。 event.waitUntil() 方法接受一个promise,并使用它来知道安装需要多长时间,以及它是否成功。 如果成功缓存了所有文件,那么将安装 Service Worker。如果其中的一个文件下载失败,那么安装步骤将失败。如果缓存文件列表过长,将会增大失败的几率。

var CACHE_NAME = 'my-cache';
var urlsToCache = [
  '/',
  '/styles/main.css',
  '/script/main.js'
];

self.addEventListener('install', function(event) {
  event.waitUntil(
    caches.open(CACHE_NAME)
      .then(function(cache) {
        console.log('Opened cache');
        return cache.addAll(urlsToCache);
      })
  );
});

3.激活

接下来就是进入激活状态:Activate。 在这个状态可以更新 Service Worker。

  1. 用户导航至站点时,浏览器会尝试在后台重新下载定义 Service Worker 的脚本文件。 如果 Service Worker 文件与其当前所用文件存在字节差异,则将其视为新 Service Worker。
  2. 新 Service Worker 将会启动,且将会触发 install 事件。
  3. 旧 Service Worker 仍控制着当前页面,因此新 Service Worker 将进入 waiting 状态。
  4. 当网站上当前打开的页面关闭时,旧 Service Worker 将会被终止,新 Service Worker 将会取得控制权。
  5. 新 Service Worker 取得控制权后,将会触发其 activate 事件。
self.addEventListener('activate', function(event) {
var cacheAllowlist = ['pages-cache-v1', 'blog-posts-cache-v1'];
event.waitUntil(
    caches.keys().then(function(cacheNames) {
      return Promise.all(
        cacheNames.map(function(cacheName) {
          if (cacheAllowlist.indexOf(cacheName) === -1) {
            return caches.delete(cacheName);
          }
        })
      );
    })
  );
});

缓存与请求响应优化

策略

  • 缓存优先
  • 网络优先
  • 仅使用缓存
  • 仅使用网络
  • 速度优先

一旦安装了 Service Worker 并且用户导航到其他页面或刷新当前页面,Service Worker 将开始监听 fetch 事件。

缓存优先策略的工作流程:首先,它会监听浏览器的 fetch 事件,拦截原始的请求。接着,它会检查缓存中是否存在即将请求的资源,如果存在,则直接返回缓存中的资源。然后,它会发起远程请求来获取最新资源,将资源缓存起来,并返回给页面。

self.addEventListener('fetch', function(event) {
  event.respondWith(
    caches.match(event.request)
      .then(function(response) {
        if (response) {
          return response;
        }
        var fetchRequest = event.request.clone();

        return fetch(fetchRequest).then(
          function(response) {
            if(!response || response.status !== 200 || response.type !== 'basic') {
              return response;
            }

            var responseToCache = response.clone();

            caches.open(CACHE_NAME)
              .then(function(cache) {
                cache.put(event.request, responseToCache);
              });

            return response;
          }
        );
      })
    );
});

什么是 PWA?

PWA 是一种使用现代 Web API 和传统的渐进性增强策略来创建跨平台 Web 应用程序的方法。它结合了 Web 应用程序的可发现性、易安装性和可链接性,以及原生应用的性能和交互体验。

优点

渐进性

PWA 适用于所有浏览器,因为它是以渐进性增强作为宗旨开发的,用户无需担心浏览器兼容性问题。

连接无关性

PWA 可以在离线或网络较差的情况下正常访问,依赖于 Service Worker 技术,这使得用户体验更稳定。

类原生应用

由于是在 App Shell 模型基础上开发,PWA 具有与原生应用相似的用户交互体验,为用户提供了更高的满意度。

持续更新

PWA 始终保持最新状态,无需用户手动更新,这消除了版本管理的烦恼。

安全性

通过 HTTPS 协议提供服务,保护用户数据不被窥探,并确保内容不被篡改。

可索引

PWA 的 manifest 文件和 Service Worker 可以被搜索引擎索引,提高应用的可见性。

黏性

通过推送离线通知等功能,PWA 可以吸引用户回流,提高用户参与度。

可安装

用户可以将常用的 Web App 添加到桌面,无需前往应用商店下载安装,提高了可用性。

可链接

通过简单的链接即可分享内容,无需下载和安装,便捷实用。

缺点

对系统功能的访问权限较低

与原生应用相比,PWA 对设备的系统功能访问权限相对较低,某些高级功能可能受到限制。

没有统一的审查标准

与应用商店不同,PWA 没有统一的审查标准,这可能导致一些质量参差不齐的应用进入市场。

核心技术

3. 核心技术

  • Web App Manifest Web App Manifest(Web 应用程序清单)概括地说是一个以 JSON 形式集中书写页面相关信息和配置的文件。
{
  "name": "My PWA",
  "short_name": "PWA",
  "start_url": "/index.html",
  "display": "standalone",
  "background_color": "#ffffff",
  "theme_color": "#007bff",
  "icons": [
    {
      "src": "/icons/icon-192x192.png",
      "sizes": "192x192",
      "type": "image/png"
    },
    {
      "src": "/icons/icon-512x512.png",
      "sizes": "512x512",
      "type": "image/png"
    }
  ]
}

  • start_url 可以设置启动网址
  • icons 会帮我萌设置各个分辨率下页面的图标
  • background_color 会设置背景颜色, Chrome 在网络应用启动后会立即使用此颜色,这一颜色将保留在屏幕上,直至网络应用首次呈现为止
  • theme_color 会设置主题颜色
  • display 设置启动样式
  • Service Worker
  • Notifications API 通知API
  • Push API 推送API 推送 API 可以用来从服务端推送新的内容而无需客户端介入,它是由应用的 Service Worker 来实现的;通知功能则可以通过 Service Worker 来向用户展示一些新信息,或者至少提醒用户应用已经更新了某些功能。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1036532.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【hadoop3.x】一 搭建集群调优

一、基础环境安装 https://blog.csdn.net/fen_dou_shao_nian/article/details/120945221 二、hadoop运行环境搭建 2.1 模板虚拟机环境准备 0)安装模板虚拟机,IP 地址 192.168.10.100、主机名称 hadoop100、内存 4G、硬盘 50G 1)hadoop100…

MongoDB基础详解

一、MongoDB概述 MongoDB 是一个基于 分布式文件存储 的开源 NoSQL 数据库系统,由 C 编写的。MongoDB 提供了 面向文档 的存储方式,操作起来比较简单和容易,支持“无模式”的数据建模,可以存储比较复杂的数据类型,是一…

MySQL的general日志

起因是一个客户的MySQL数据的data目录下会生成一个 名为ubuntu.log的日志且文件占用空间极大,平均每2周500G,所以才产生了处理该问题的想法。后来查询了相关资料其实就是一般日志开启了,但是又未指定其路径及名称所以就会一头雾水。 MySQL的g…

关于华为笔记本谷歌浏览器(chrome)默认启动页为360搜索的解决方法

一、简介 好久没打开谷歌浏览器,近期发现谷歌浏览器的启动是360搜素,现象比较常见,一开始以为是被各种病毒或插件拦截,经过很多尝试方法: 修改浏览器启动页设置【无效】修改快捷方式的“目标位置”属性【无效】修改&…

MySQL:码包安装mysql(5.6.51)

我们去下载mysql源码安装包和cmake包 安装mysql的时候需要使用到cmake,其次我们还要使用yum安装一些环境 yum -y install ncurses-devel gcc-c gcc openssl* perl* 下载mysql源码包 http://mirrors.sohu.com/mysql/MySQL-5.6/mysql-5.6.51.tar.gzhttp://mirrors.s…

WebRTC之丢包重传协议

丢包处理可以使用FEC前向纠错、NACK丢包重传。上一篇文章咱们介绍过前向纠错,现在来探讨丢包重传。首先是接收端发送基于RTCP反馈的请求,发送端收到请求后重传指定packet包。 1、重传包格式 重传包的格式由RTP头、OSN、原始payload数据组成。OSN表示原…

Prometheus+Grafana实现监控报警

文章目录 一、PrometheusGrafana实现监控报警1.1 各项服务端口1.2 说明 二、部署2.1 展示 一、PrometheusGrafana实现监控报警 Prerequired K8s集群 1.1 各项服务端口 Service版本DescriptionPortNode-exporter1.6.1采集机器的各项监控指标9100Pushgatewayv1.6.2可手动push…

goadmin 学习笔记

1.安装命令行 Following three steps to run it. Note: now you can quickly start by doing like this. $ go install github.com/GoAdminGroup/admlatest $ mkdir new_project && cd new_project $ adm init Or (use adm whose version higher or equal than v1.…

给yarn/npm包管理设置代理加速nodejs依赖下载的方法

由于墙内网络干扰屏蔽国外网络的原因&#xff0c;在国内下载nodejs依赖是非常缓慢的。 所以为了解决这个问题&#xff0c;必须设置代理&#xff0c;具体方法如下&#xff1a; NPM设置代理&#xff1a; npm config set proxy<http_proxy> NPM删除代理&#xff1a; npm c…

Zookeeper-集群介绍与核心理论

Zookeeper集群 4.Zookeeper集群4.1) 介绍4.2) 核心理论 4.Zookeeper集群 4.1) 介绍 Leader选举&#xff1a; Serverid&#xff1a;服务器ID。比如有三台服务器&#xff0c;编号分别是1,2,3。编号越大在选择算法中的权重越大。Zxid&#xff1a;数据ID。服务器中存放的最大数据…

【力扣每日一题】2023.9.24 LRU缓存

目录 题目&#xff1a; 示例&#xff1a; 分析&#xff1a; 代码&#xff1a; 题目&#xff1a; 示例&#xff1a; 分析&#xff1a; 这又是一道程序设计类的题目&#xff0c;要我们实现LRU缓存的get和put操作。 简单说一下LRU缓存是什么&#xff0c;在我看来就是实用主义…

2023年kali linux安装中文输入法

apt-get install fcitx 安装输入法框架 apt-get install fcitx-googlepinyin 安装谷歌输入法 reboot &#xff0c;重启系统重启之后右上有个小键盘点击里面的配置 添加google输入法 把Google pinyin上移置顶 验证输入法【CtrlSpace 切换输入法】

vue3 - Element Plus暗黑模式适配、切换及自定义颜色

GitHub Demo 地址 在线预览 Element Plus 2.2.0 版本开始支持暗黑模式&#xff0c;启用方式参考 Element Plus 官方文档 - 暗黑模式 demo通过Element Plus和VueUse 的 useDark 方法实现具有自动数据持久性的响应式暗黑模式。 安装 npm install element-plus --save npm in…

【owt】vs2022 + v141 : 查看WINDOWSSDKDIR

confmfc改为vs2022 + v141 构建 去掉这几个boost库,一样可以链接ok libboost_system-vc141-mt-sgd-x32-1_67.lib libboost_date_time-vc141-mt-sgd-x32-1_67.lib libboost_random-vc141-mt-sgd-x32-1_67.libSDK不在2022或者2017 里面? WINDOWSSDKDIR 在哪里? ##

设计模式之观察者(发布订阅)模式

观察者模式定义了一种一对多的依赖关系&#xff0c;让多个观察者对象同事监听某一个主题对象。这个主题对象在状态发生变化时&#xff0c;会通知所有观察者对象&#xff0c;使它们能够自动更新自己 class Program{static void Main(string[] args){ConcreteSubject concreteSu…

[管理与领导-101]:IT人对高情商的误解?什么是高情商?

目录 前言&#xff1a; 一、人的心理架构 1.1 心理的基本过程 1.2 心理架构 1.3 冰山模型 1.4 IT人不同角度看人的能力层次 二、什么是智商和专业技能 2.1 什么是智商 2.2 什么是专业技能&#xff1a;表层 2.3 IT技术人员的智商和专业技能的重要性 2.4 IT技术人员的…

H.264编码

1.为什么要对视频进行编码 视频是连续的图像序列&#xff0c;由连续的帧构成&#xff0c;一帧即为一幅图像&#xff0c;由于人眼的视觉暂留效应&#xff0c;当帧序列以一定的速率播放时&#xff0c;我们看到的就是动作连续的视频&#xff0c;这么多连续的图像数据如果不经过编码…

在python3上使用pyautogui模拟鼠标键盘操作删除垃圾邮件

在PyPI The Python Package Index网站上搜索pyautogui&#xff0c;可以看到最新版本python3可用&#xff0c;本机环境&#xff1a;win7 64位&#xff0c;python3.8.10。之前写过一篇python2的文章&#xff0c;参考用python使用pyautogui库实现按键精灵模拟鼠标键盘找图的功能_…

如何看待unity新的收费模式

Unity的由来&#xff1a; Unity 是一款跨平台的游戏引擎&#xff0c;由 Unity Technologies 公司开发和维护。Unity 的起源可以追溯到 2002 年&#xff0c;当时 Unity Technologies 创始人之一的 David Helgason 在丹麦创建了一个名为 Over the Edge Entertainment 的游戏开发…

GLTF编辑器教你区分自发光贴图和光照贴图

什么自发光贴图 自发光贴图&#xff08;Emissive Mapping&#xff09;是一种用于在计算机图形学中模拟自发光效果的技术。它可以将光源直接嵌入纹理贴图中&#xff0c;以模拟物体表面具有发光效果的材质。 传统的纹理贴图只能模拟物体表面的颜色和纹理&#xff0c;无法模拟物体…