浏览器原理 26 # 渐进式网页应用(PWA):它究竟解决了Web应用的哪些问题?

简介: 浏览器原理 26 # 渐进式网页应用(PWA):它究竟解决了Web应用的哪些问题?

说明

浏览器工作原理与实践专栏学习笔记



什么是 PWA

PWA,全称是 Progressive Web App,翻译过来就是渐进式网页应用。根据字面意思,它就是“渐进式 +Web 应用”。


PWA 所支持的首先是一个 Web 页面。


“渐进式”的理解:


   站在 Web 应用开发者来说,PWA 提供了一个渐进式的过渡方案,让 Web 应用能逐步具有本地应用的能力。采取渐进式可以降低站点改造的代价,使得站点逐步支持各项新技术,而不是一步到位。


   站在技术角度来说,PWA 技术也是一个渐进式的演化过程,在技术层面会一点点演进,比如逐渐提供更好的设备特性支持,不断优化更加流畅的动画效果,不断让页面的加载速度变得更快,不断实现本地应用的特性。

PWA 的定义:它是一套理念,渐进式增强 Web 的优势,并通过技术手段渐进式缩短和本地应用或者小程序的距离。



Web 应用 VS 本地应用


Web 缺陷


Web 应用缺少离线使用能力,在离线或者在弱网环境下基本上是无法使用的。而用户需要的是沉浸式的体验,在离线或者弱网环境下能够流畅地使用是用户对一个应用的基本要求。


Web 应用还缺少了消息推送的能力,因为作为一个 App 厂商,需要有将消息送达到应用的能力。


Web 应用缺少一级入口,也就是将 Web 应用安装到桌面,在需要的时候直接从桌面打开 Web 应用,而不是每次都需要通过浏览器来打开。


PWA 两种解决方案

  • 通过引入 Service Worker 来试着解决离线存储和消息推送的问题
  • 通过引入 manifest.json 来解决一级入口的问题



PWA 提供了 manifest.json 配置文件,可以让开发者自定义桌面的图标、显示名称、启动方式等信息,还可以设置启动画面、页面主题颜色等信息。


chrome扩展:manifest.json文件详解


一个manifest.json格式如下:

{ 
    // 必须的字段3个
    "name": "MyExtension", // 扩展名称
    "version": "1.0", // 版本。由1到4个整数构成。多个整数间用"."隔开
    "manifest_version": 2, // manifest文件版本号。Chrome18开始必须为2
    // 建议提供的字段3个
    "description": "",   // 描述。132个字符以内
    "icons": {
       "16": "image/icon-16.png",
       "48": "image/icon-48.png",
       "128": "image/icon-128.png"
    }, //扩展图标。推荐大小16,48,128
    "default_locale": "en", // 国际化
    // 以下字段多选一,或者都不提供
    "browser_action": {
       "default_icon": "image/icon-128.png",
        "default_title": "My Test",
       "default_popup": "html/browser.html"
    }, //地址栏右侧图标管理。含图标及弹出页面的设置等
    "page_action": {
        "default_icon": "image/icon-48.png",
        "default_title": "My Test",
        "default_popup": "html/page.html"
    }, //地址栏最后附加图标。含图标及行为等
    "theme": {}, // 主题,用于更改整个浏览器的外观
    "app": {}, // 指定扩展需要跳转到的URL
    // 根据需要提供
    "background": {
       "scripts": [
           "lib/jquery-3.3.1.min.js",
           "js/background.js"
       ] ,
        "page":"html/background.html"
    }, // 指定扩展进程的background运行环境
    "chrome_url_overrides": {
       "pageToOverride": "html/overrides.html"
    }, //替换页面。详见注释1
    "content_scripts": [{
      "matches": ["https://www.baidu.com/*"],
      "css": ["css/mystyles.css"],
      "js": ["lib/jquery-3.3.1.min.js", "js/content.js"]
    }], // 指定在web页面运行的脚本。详见注释2
    "content_security_policy": "",  // 安全策略
    "file_browser_handlers": [],   
    "homepage_url": "http://xxx", // 扩展的官方主页
    "incognito": "spanning", // 或"split"。详见注释3
    "intents": {}, // 用户操作意图描述
    "key": "", // 扩展唯一标识。不需要人为指定
    "minimum_chrome_version": "1.0", // 扩展所需chrome的最小版本
    "nacl_modules": [],  // 消息与本地处理模块映射
    "offline_enabled": true, // 是否允许脱机运行
    "omnibox": {
       "keyword": "myKey"
    }, //ominbox即地址栏。用于响应地址栏的输入事件
    "options_page": "aFile.html", // 选项页。用于在扩展管理页面跳转到选项设置
    "permissions": [
       "https://www.baidu.com/*",
       "background",
       "tabs"
    ], //权限。详见注释4
    "plugins": [{
       "path": "extension_plugin.dll",
       "public": true
    }], // 扩展。可调用第三方扩展
    "requirements": {}, // 指定所需要的特殊技术。目前只支持"3D"
    "update_url": "http://path/to/updateInfo.xml",   // 自动升级
    "web_accessible_resources": [] // 指定资源路径,为String数组
}



什么是 Service Worker


在 2014 年的时候,标准委员会就提出了 Service Worker 的概念,它的主要思想是在页面和网络之间增加一个拦截器,用来缓存和拦截请求。


   在 Service Worker 之前,WHATWG 小组就推出过用 App Cache 标准来缓存页面,不过在使用过程中 App Cache 所暴露的问题比较多,遭到多方吐槽。


Service Worker 的主要功能就是拦截请求和缓存资源。


Service Worker 结构示意图


下图可以看出:WebApp 请求资源时,会先通过 Service Worker,让它判断是返回 Service Worker 缓存的资源还是重新去网络请求资源。


20210526171224280.png


Service Worker 的设计思路


1. 架构

Service Worker 来自 Web Worker 的一个核心思想:让其运行在主线程之外。


   前面聊过:Web Worker 的目的是让 JavaScript 能够运行在页面主线程之外,不过由于 Web Worker 中是没有当前页面的 DOM 环境的,所以在 Web Worker 中只能执行一些和 DOM 无关的 JavaScript 脚本,并通过 postMessage 方法将执行的结果返回给主线程。


   Service Worker 需要在 Web Worker 的基础之上加上储存功能


   Service Worker 需要会为多个页面提供服务,不能把 Service Worker 和单个页面绑定起来


2. 消息推送

推荐文章:Service Worker学习与实践(三)——消息推送


下面部分来自该文:


Service Worker 中的消息推送是基于 Notification API的,这一API的使用首先需要用户授权,通过在 Service Worker 注册时的serviceWorkerRegistration.pushManager.subscribe 方法来向用户申请权限,如果用户拒绝了消息推送,应用程序也需要相关处理。


消息推送是基于谷歌云服务的,因此,在国内,收到 GFW (防火长城计划)的限制,这一功能的支持并不好,Google提供了一系列推送相关的库。


例如:Node.js中,使用 web-push来实现。


   The common use case for this library is an application server using a GCM API key and VAPID keys.

const webpush = require('web-push');
// VAPID keys should be generated only once.
const vapidKeys = webpush.generateVAPIDKeys();
webpush.setGCMAPIKey('<Your GCM API Key Here>');
webpush.setVapidDetails(
  'mailto:example@yourdomain.org',
  vapidKeys.publicKey,
  vapidKeys.privateKey
);
// This is the same output of calling JSON.stringify on a PushSubscription
const pushSubscription = {
  endpoint: '.....',
  keys: {
    auth: '.....',
    p256dh: '.....'
  }
};
webpush.sendNotification(pushSubscription, 'Your Push Payload Text');

一般原理是:在服务端生成公钥和私钥,并针对用户将其公钥和私钥存储到服务端,客户端只存储公钥。Service Worker的swReg.pushManager.subscribe 可以获取到 subscription,并发送给服务端,服务端利用 subscription 向指定的用户发起消息推送。


消息推送功能可以配合 clients API 做特殊处理。


如果用户安装了PWA应用,即使用户关闭了应用程序,Service Worker也在运行,即使用户未打开应用程序,也会收到消息通知。




3. 安全

关于安全,其中最为核心的一条就是 HTTP。


   HTTP 采用的是明文传输信息,存在被窃听、被篡改和被劫持的风险


   HTTPS 的通信数据都是经过加密的,即便拦截了数据,也无法破解数据内容,而且 HTTPS 还有校验机制,通信双方很容易知道数据是否被篡改


要使站点支持 Service Worker,首先必要的一步就是要将站点升级到 HTTPS。


Service Worker 还需要同时支持 Web 页面默认的安全策略,诸如同源策略、内容安全策略(CSP)等






目录
相关文章
|
6天前
|
前端开发 安全 JavaScript
构建高效Web应用:前后端分离架构的实践
【9月更文挑战第4天】在数字时代,Web应用已成为企业与用户互动的主要平台。本文将介绍如何通过前后端分离的架构设计来构建高效的Web应用,探讨该架构的优势,并分享实现过程中的关键步骤和注意事项。文章旨在为开发者提供一种清晰、高效的开发模式,帮助其在快速变化的市场环境中保持竞争力。
|
11天前
|
中间件 编译器 数据处理
在web开发中应用管道过滤器
【9月更文挑战第1天】本文介绍管道-过滤器架构将数据处理流程分解为一系列独立组件,通过管道连接,适用于数据流处理如图像处理、编译器设计等。通过具体实例说明了Gin如何有效支持管道-过滤器风格的设计,构建高性能Web服务。
29 9
|
11天前
|
开发者 图形学 API
从零起步,深度揭秘:运用Unity引擎及网络编程技术,一步步搭建属于你的实时多人在线对战游戏平台——详尽指南与实战代码解析,带你轻松掌握网络化游戏开发的核心要领与最佳实践路径
【8月更文挑战第31天】构建实时多人对战平台是技术与创意的结合。本文使用成熟的Unity游戏开发引擎,从零开始指导读者搭建简单的实时对战平台。内容涵盖网络架构设计、Unity网络API应用及客户端与服务器通信。首先,创建新项目并选择适合多人游戏的模板,使用推荐的网络传输层。接着,定义基本玩法,如2D多人射击游戏,创建角色预制件并添加Rigidbody2D组件。然后,引入网络身份组件以同步对象状态。通过示例代码展示玩家控制逻辑,包括移动和发射子弹功能。最后,设置服务器端逻辑,处理客户端连接和断开。本文帮助读者掌握构建Unity多人对战平台的核心知识,为进一步开发打下基础。
32 0
|
11天前
|
Rust 安全 开发者
惊爆!Xamarin 携手机器学习,开启智能应用新纪元,个性化体验与跨平台优势完美融合大揭秘!
【8月更文挑战第31天】随着互联网的发展,Web应用对性能和安全性要求不断提高。Rust凭借卓越的性能、内存安全及丰富生态,成为构建高性能Web服务器的理想选择。本文通过一个简单示例,展示如何使用Rust和Actix-web框架搭建基本Web服务器,从创建项目到运行服务器全程指导,帮助读者领略Rust在Web后端开发中的强大能力。通过实践,读者可以体验到Rust在性能和安全性方面的优势,以及其在Web开发领域的巨大潜力。
22 0
|
11天前
|
开发者 Java 前端开发
Struts 2验证框架:如何让数据校验成为Web开发的隐形守护者?揭秘前后端一致性的秘诀
【8月更文挑战第31天】在现代Web开发中,数据验证对确保应用健壮性和良好用户体验至关重要。随着前后端分离架构的普及,保证数据校验一致性尤为关键。Struts 2 验证框架基于 JavaBean 验证 API(JSR 303/JSR 380),允许开发者通过注解或 XML 配置轻松定义验证规则,确保输入数据在执行业务逻辑前已通过验证。此外,Struts 2 支持与前端 JavaScript 验证相结合,确保前后端数据校验一致,提升用户体验。通过注解、XML 配置和资源文件,开发者可以轻松定义和调整验证规则,实现前后端一致的数据校验,提高应用健壮性。
21 0
|
11天前
|
Java 缓存 数据库连接
揭秘!Struts 2性能翻倍的秘诀:不可思议的优化技巧大公开
【8月更文挑战第31天】《Struts 2性能优化技巧》介绍了提升Struts 2 Web应用响应速度的关键策略,包括减少配置开销、优化Action处理、合理使用拦截器、精简标签库使用、改进数据访问方式、利用缓存机制以及浏览器与网络层面的优化。通过实施这些技巧,如懒加载配置、异步请求处理、高效数据库连接管理和启用GZIP压缩等,可显著提高应用性能,为用户提供更快的体验。性能优化需根据实际场景持续调整。
35 0
|
11天前
|
Java 数据库连接 Spring
Struts 2 插件开发竟如魔法盛宴,为框架注入超能力,开启奇幻编程之旅!
【8月更文挑战第31天】在Web开发中,Struts 2插件开发允许我们在不改动框架核心代码的前提下,通过创建实现特定接口的Java类来扩展框架功能、调整其行为或促进与其他框架(如Spring、Hibernate)的集成,从而更好地满足特定业务需求。遵循良好的设计原则与实践,能够确保插件的高效稳定运行并提升整体项目的可维护性。具体步骤包括创建项目、定义插件类、实现初始化与销毁逻辑,并将插件部署至应用中。
33 0
|
11天前
|
数据库 开发者 Python
web应用开发
【9月更文挑战第1天】web应用开发
26 1
|
7天前
|
数据采集 Java 数据挖掘
Java IO异常处理:在Web爬虫开发中的实践
Java IO异常处理:在Web爬虫开发中的实践
|
9天前
|
前端开发 JavaScript 持续交付
Web应用开发的方法
Web应用开发的方法
11 1