渐进式 Web 应用(PWA)

  • 运用现代的 Web API 以及传统的渐进式增强策略来创建跨平台 Web 应用程序。

PWA 的优势

PWA 介绍

  • 桌面和移动设备上的所有主流浏览器都支持 service worker。
  • Web App Manifest(安装),Push(通知接收),Notifications(通知显示)和 Add to Home Screen(添加到屏幕) 功能也得到了广泛的支持。
  • 目前,Safari 对 Web App Manifest 和 Add to Home Screen 的支持有限,并且不支持 Web 推送通知。
  • 应该遵循渐进增强规则 - 仅在支持它们的情况下使用提供此类增强功能的技术

PWA 结构

  • 最流行的方法是“app shell”概念,它完全按照上述方式混合SSR(服务端渲染)和CSR(浏览器端渲染),此外还遵循“离线优先”方法
  • 一种涉及Streams API(流)的新方法

App shell

  • App shell意图尽快加载最小的用户界面,然后缓存它,以便在后续访问时可以离线使用,然后加载应用程序的所有内容。
  • 通过service worker控制从服务器请求的内容以及从缓存中检索的内容
  • 响应式网页设计也适用于渐进式网络应用程序,使用 viewport meta tag,CSS media queries,Flexbox,和 CSS Grid 等技术。
    • viewport meta tag:<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">meta标签
    • CSS media queries:@media (max-width: 600px) {css媒体查询
    • Flexbox:弹性盒子布局
    • CSS Grid:CSS 网格布局

Streams API(实验功能)

  • 流将你希望通过网络接收的资源拆分成小块,然后按位处理它。
  • 浏览器在接收用于显示web页面的资源时就是这么处理的,例如:视频缓冲区和更多的内容可以逐渐播放,有时候随着内容的加载,你可以看到图像逐渐地显示。
  • Streams API出现以前,流对于JavaScript是不可用的。以前,如果我们想要处理某种资源(如视频、文本文件等),我们必须下载完整的文件,等待它反序列化成适当的格式,然后在完整地接收到所有的内容后再进行处理。
  • It provides fine-grained control — the stream can be started, chained with another stream, cancelled, checked for errors, and more.(它提供了细粒度的控制——流可以启动、与另一个流链接、取消、检查错误等等。)

Structure of our example application(示例)

  • 需要重读实例

通过 Service workers 让 PWA 离线工作

Service workers 解释

  • Service Workers是浏览器和网络之间的虚拟代理。解决了如何正确缓存网站资源并使其在用户设备离线时可用。
  • 运行在一个与我们页面的 JavaScript 主线程独立的线程上
  • 对 DOM 结构没有任何访问权限
  • 可以在不同的上下文之间发送和接收信息
  • 不仅仅提供离线功能,还提供包括处理通知,在单独的线程上执行繁重的计算等
  • 可以控制网络请求,修改网络请求,返回缓存的自定义响应,或合成响应。
  • 其内的 API 都是非阻塞(异步的)

安全

  • Service Workers 只能在安全的上下文中执行(即 HTTPS )
  • 如果您想在将代码推送到生产环境之前先进行实验,则可以始终在本地主机上进行测试或设置 GitHub 页面 - 两者都支持HTTPS。

离线优先

PWA 渐进增强

js13kPWA应用程序中的 Service workers

注册 Service Worker

  • 注意这里是navigator下的一个方法,用来注册 Service Worker
if('serviceWorker' in navigator) {
navigator.serviceWorker.register('/pwa-examples/js13kpwa/sw.js');
};

Service Worker 的声明周期

  • 注册完成后,sw.js 文件会自动下载,然后安装,最后激活。

安装

  • In the install listener, we can initialize the cache and add files to it for offline use. Our js13kPWA app does exactly that.(在安装侦听器中,我们可以初始化缓存并向其中添加文件以供脱机使用。)
  • The service worker does not install until the code inside waitUntil is executed. It returns a promise(在执行e.waitUntil内的代码前,service worker 不会被安装?它会返回一个 promise)
  • caches is a special CacheStorage object available in the scope of the given Service Worker to enable saving data(caches 是一个CacheStorage 对象,用于保存数据,它是异步的)
  • we open a cache with a given name, then add all the files our app uses to the cache, so they are available next time it loads (identified by request URL).(通过给定名称cacheName区分不同缓存库,通过请求URL标识不同缓存)
var cacheName = 'js13kPWA-v1';
var appShellFiles = [
'/pwa-examples/js13kpwa/',
'/pwa-examples/js13kpwa/index.html',
'/pwa-examples/js13kpwa/app.js',
'/pwa-examples/js13kpwa/style.css',
'/pwa-examples/js13kpwa/fonts/graduate.eot',
'/pwa-examples/js13kpwa/fonts/graduate.ttf',
'/pwa-examples/js13kpwa/fonts/graduate.woff',
'/pwa-examples/js13kpwa/favicon.ico',
'/pwa-examples/js13kpwa/img/js13kgames.png',
'/pwa-examples/js13kpwa/img/bg.png',
'/pwa-examples/js13kpwa/icons/icon-32.png',
'/pwa-examples/js13kpwa/icons/icon-64.png',
'/pwa-examples/js13kpwa/icons/icon-96.png',
'/pwa-examples/js13kpwa/icons/icon-128.png',
'/pwa-examples/js13kpwa/icons/icon-168.png',
'/pwa-examples/js13kpwa/icons/icon-192.png',
'/pwa-examples/js13kpwa/icons/icon-256.png',
'/pwa-examples/js13kpwa/icons/icon-512.png'
]; self.addEventListener('install', function(e) {
console.log('[Service Worker] Install');
e.waitUntil(
caches.open(cacheName).then(function(cache) {
console.log('[Service Worker] Caching all: app shell and content');
return cache.addAll(contentToCache);
})
);
});

Activation(激活)

  • There is also an activate event, which is used in the same way as install. (还有一个activate事件,与install的使用方式相同。)
  • This event is usually used to delete any files that are no longer necessary and clean up after the app in general. (此事件通常用于删除不再需要的任何文件,并在应用程序运行后进行清理。)

Responding to fetches 处理请求和缓存响应

  • We also have a fetch event at our disposal, which fires every time an HTTP request is fired off from our app. (有一个fetch事件供我们使用,它在每次从我们的应用程序发出HTTP请求时都会触发。)
  • The response can be anything we want: the requested file, its cached copy, or a piece of JavaScript code that will do something specific(响应可以是我们想要的任何东西:请求的文件、其缓存副本或一段可以执行特定操作的javascript代码。)
  • The FetchEvent.respondWith method takes over control — this is the part that functions as a proxy server between the app and the network. (FetchEvent.respondWith接管了请求的控制权,这应用程序和服务器间充当代理服务器)
self.addEventListener('fetch', function(e) {
e.respondWith(
caches.match(e.request).then(function(r) {
console.log('[Service Worker] Fetching resource: '+e.request.url);
return r || fetch(e.request).then(function(response) {
return caches.open(cacheName).then(function(cache) {
console.log('[Service Worker] Caching new resource: '+e.request.url);
cache.put(e.request, response.clone());
return response;
});
});
})
);
});

Updates(升级)

  • how do you upgrade a Service Worker when a new version of the app containing new assets is available? The version number in the cache name is key to this:(通过修改cacheName来升级缓存库,建议缓存库名附带版本号来区分)
  • When this updates to v2, we can then add all of our files (including our new files) to a new cache:(把旧版本的缓存写入新缓存)
  • the available cache space in the browser is limited, so it is a good idea to clean up after ourselves.(浏览器中可用的缓存空间有限,因此最好自己清理。)
var cacheName = 'js13kPWA-v1';

Clearing the cache(清空缓存库)

  • 删除不在当前版本的数据?
self.addEventListener('activate', function(e) {
e.waitUntil(
caches.keys().then(function(keyList) {
return Promise.all(keyList.map(function(key) {
if(cacheName.indexOf(key) === -1) {
return caches.delete(key);
}
}));
})
);
});

Other use cases(其他示例)

  • Performance-wise, you can prefetch resources that are not needed right now, but might be in the near future, so the app will be faster when you actually need those resources.(可以用来预加载数据)

Summary(总结)

  • Service Workers are also used when dealing with push notifications(处理推送通知时也使用 Service Workers)

How to make PWAs installable(使PWA可安装)

Requirements(可安装的条件)

  • To make the website installable, it needs the following things in place:(条件)

    • The website to be served from a secure (HTTPS) domain(从安全(https)域提供服务的网站)
    • A service worker registered, to make the app work offline (this is required only by Chrome for Android currently)(安卓下的谷歌浏览器需要service worker被注册才支持安装到桌面)

The manifest file

PWA - 整体(未完)的更多相关文章

  1. Java开发中的23+2种设计模式学习个人笔记(未完待续)

    注:个人笔记 一.设计模式分三大类: 创建型模式,共五种:工厂方法模式.抽象工厂模式.单例模式.建造者模式.原型模式. 结构型模式,共七种:适配器模式.装饰器模式.代理模式.外观模式.桥接模式.组合模 ...

  2. Reading | 《数字图像处理原理与实践(MATLAB版)》(未完待续)

    目录 一.前言 1.MATLAB or C++ 2.图像文件 文件头 调色板 像素数据 3.RGB颜色空间 原理 坐标表示 4.MATLAB中的图像文件 图像类型 image()函数 imshow() ...

  3. javascript有用小功能总结(未完待续)

    1)javascript让页面标题滚动效果 代码如下: <title>您好,欢迎访问我的博客</title> <script type="text/javasc ...

  4. ASP.NET MVC 系列随笔汇总[未完待续……]

    ASP.NET MVC 系列随笔汇总[未完待续……] 为了方便大家浏览所以整理一下,有的系列篇幅中不是很全面以后会慢慢的补全的. 学前篇之: ASP.NET MVC学前篇之扩展方法.链式编程 ASP. ...

  5. 关于DOM的一些总结(未完待续......)

    DOM 实例1:购物车实例(数量,小计和总计的变化) 这里主要是如何获取页面元素的节点: document.getElementById("...") cocument.query ...

  6. 我的SQL总结---未完待续

    我的SQL总结---未完待续 版权声明:本文为博主原创文章,未经博主允许不得转载. 总结: 主要的SQL 语句: 数据操作(select, insert, delete, update) 访问控制(g ...

  7. virtualbox搭建ubuntu server nginx+mysql+tomcat web服务器1 (未完待续)

    virtualbox搭建ubuntu server nginx+mysql+tomcat web服务器1 (未完待续) 第一次接触到 linux,不知道linux的确很强大,然后用virtualbox ...

  8. MVC丶 (未完待续······)

         希望你看了此小随 可以实现自己的MVC框架     也祝所有的程序员身体健康一切安好                                                     ...

  9. 一篇文章让Oracle程序猿学会MySql【未完待续】

    一篇文章让Oracle DB学会MySql[未完待续] 随笔前言: 本篇文章是针对已经能够熟练使用Oracle数据库的DB所写的快速学会MySql,为什么敢这么说,是因为本人认为Oracle在功能性方 ...

  10. [教程] [承風雅傳HSU]用ES4封裝Win7---ES4 Win7封裝教程(未完待續)

    [教程] [承風雅傳HSU]用ES4封裝Win7---ES4 Win7封裝教程(未完待續) a10036it 发表于 2015-7-27 21:11:19 https://www.itsk.com/t ...

随机推荐

  1. CentOS与Ubuntu的区别

    学习博客:https://www.cnblogs.com/lirongzheng/p/8250511.html 更多Ubuntu相关信息见Ubuntu 专题页面 http://www.linuxidc ...

  2. 修改centos7容器的时间和宿主机时间一致

    一.问题 centos7系统容器时间与宿主机系统时间不一致,就进去查看一番,发现时区和宿主机上的时间不一致,下面就来解决一下 二.现象 1.查看centos宿主机的时间 输入如下命令查看 # date ...

  3. 修饰符 public、 private 和 protected和区别

    TypeScript 可以使用三种访问修饰符(Access Modifiers),分别是 public.private 和 protected. public 修饰的属性或方法是公有的,可以在任何地方 ...

  4. K8S ConfigMap使用

    k8s系列文章: 什么是K8S configmap是k8s的一个配置管理组件,可以将配置以key-value的形式传递,通常用来保存不需要加密的配置信息,加密信息则需用到Secret,主要用来应对以下 ...

  5. 【Web性能权威指南】 PDF

    Web性能权威指南.pdf 网盘:https://545c.com/file/24657411-424998805     获取码:276922

  6. Winfrom 减少控件重绘闪烁的方法

    Winform控件的双缓冲.控件的双缓冲属性是隐藏的,可以通过反射改变其属性值. lv.GetType().GetProperty("DoubleBuffered", Bindin ...

  7. Window 系统 Excel 同时打开两个Excel 文件

    问题 我们在使用 Excel 的时候,经常需要打开多个 Excel 文件,但是默认的话我们是只打开一个窗口的.这样不便于我们操作两个 Excel . 解决办法 下载这个补丁进行安装,下载链接 http ...

  8. Python之write与writelines区别

    一.传入的参数类型要求不同: 1. file.write(str)需要传入一个字符串做为参数,否则会报错. write( "字符串") with open('20200222.tx ...

  9. Go Web爬虫并发实现

    题目:Exercise: Web Crawler 直接参考了 https://github.com/golang/tour/blob/master/solutions/webcrawler.go 的实 ...

  10. JS中let、var、const的区别

    先看let和var: 1. console.log(a); // undefined var a = 3; console.log(a); // Uncaught ReferenceError: Ca ...