frontend
玩转pwa
2020/09/02 0

# 什么是 pwa

PWA(Progressive web apps,渐进式 Web 应用)运用现代的 Web API 以及传统的渐进式增强策略来创建跨平台 Web 应用程序。这些应用无处不在、功能丰富,使其具有与原生应用相同的用户体验优势。

# 特点

当应用程序满足某些要求时,可以将其视为 PWA,或者实现一组给定的功能:离线工作,可安装,易于同步,可以发送推送通知等。

  • Discoverable, 内容可以通过搜索引擎发现。
  • Installable, 可以出现在设备的主屏幕。
  • Linkable, 你可以简单地通过一个 URL 来分享它。
  • Network independent, 它可以在离线状态或者是在网速很差的情况下运行。
  • Progressive, 它在老版本的浏览器仍旧可以使用,在新版本的浏览器上可以使用全部功能。
  • Re-engageable, 无论何时有新的内容它都可以发送通知。
  • Responsive, 它在任何具有屏幕和浏览器的设备上可以正常使用——包括手机,平板电脑,笔记本,电视,冰箱,等。
  • Safe, 在你和应用之间的连接是安全的,可以阻止第三方访问你的敏感数据。

# 优势

  • 减少应用安装后的加载时间, 多亏了 Service Workers 来进行缓存, 以此来节省带宽和时间。
  • 当应用有可用的更新时,可以仅仅去更新发生改变的那部分内容。与之相反,对于一个原生应用而言, 即便是最微小的改动也需要强制用户去再次下载整个应用。
  • 外观和使用感受与原生平台更加融为一体——应用图标被放置在主屏幕上,应用可以全屏运行,等。
  • 凭借系统通知和推送消息与用户保持连接,对用户产生更多的吸引力,并且提高转换效率。

# 浏览器支持

PWA 所需的关键要素是 service worker 支持。 值得庆幸的是,桌面和移动设备上的所有主流浏览器都支持 service worker。

其他功能,如 Web App Manifest,Push,Notifications和 Add to Home Screen 功能也得到了广泛的支持。 目前,Safari 对 Web App Manifest 和 Add to Home Screen 的支持有限,并且不支持 Web 推送通知。 但是,其他主流浏览器支持所有这些功能。

# APP shell

App shell意图尽快加载最小的用户界面,然后缓存它,以便在后续访问时可以离线使用,然后加载应用程序的所有内容。这样,下次有人从设备访问应用程序时,UI立即从缓存加载,并从服务器请求新内容(如果它已在缓存中不可用)。 这种结构很快,并且当用户立即看到内容而不是加载动画或空白页时也感觉很快。如果网络连接不可用,它还允许离线访问网站。

app shell 方法允许网站:

  • 可链接:即使它的行为类似于原生应用,它仍然是一个网站 - 您可以单击页面中的链接和当您想共享它时向某人发送URL。
  • 渐进式:从“好用的旧的基本网站”开始,逐步添加新功能,同时记住检测它们是否在浏览器中可用,并优雅地处理在没有支持的情况下出现的任何错误。例如,离线模式下 service workers 的帮助只是一个额外的特性使网站体验更好,但没有它网站应仍然是完全可用的。
  • 响应式:响应式网页设计也适用于渐进式网络应用程序,因为它们主要用于移动设备。 有许多不同的设备与浏览器 - 使您的网站适用于不同的屏幕尺寸,视口或像素密度,使用 viewport meta tag,CSS media queries,Flexbox,和 CSS Grid 等技术是很重要的。

# service worker

  • 生命周期

image

  • 事件

image

  • 注意事项

image

  • 填充缓存

install 事件会在注册完成之后触发。install 事件一般是被用来填充你的浏览器的离线缓存能力

this.addEventListener('install', function(event) {
  event.waitUntil(
    caches.open('v1').then(function(cache) {
      return cache.addAll([
        '/sw-test/',
        '/sw-test/index.html',
        '/sw-test/style.css',
        '/sw-test/app.js',
        '/sw-test/image-list.js',
        '/sw-test/star-wars-logo.jpg',
        '/sw-test/gallery/',
        '/sw-test/gallery/bountyHunters.jpg',
        '/sw-test/gallery/myLittleVader.jpg',
        '/sw-test/gallery/snowTroopers.jpg'
      ]);
    })
  );
});

  • 请求拦截

每次任何被 service worker 控制的资源被请求到时,都会触发 fetch 事件,这些资源包括了指定的 scope 内的文档,和这些文档内引用的其他任何资源,你可以给 service worker 添加一个 fetch 的事件监听器,接着调用 event 上的 respondWith() 方法来劫持我们的 HTTP 响应,然后你用可以用自己的魔法来更新他们

image

# manifest.json

{
    "name":"pwa",
    "manifest_version": 2,
    "version": "0.1",
    "short_name":"Blog",
    "display":"standalone",
    "default_locale": "en",
    "description": "a pwa app",
    "start_url":"/",
    "theme_color":"lightblue",
    "background_color":"cyan",
    "icons": {
        "48": "logo.png",
        "96": "logo.png"
      },
      "related_applications": [] //在 Android 手机上,如果 web app manifest 中包含 related_applications 和 "prefer_related_applications": true,则会将用户定向到 Google Play 商店,并提示您安装指定的本机应用。
}

# refs

  1. 渐进式 Web 应用(PWA)(opens new window)
  2. @vuepress/plugin-pwa(opens new window)
  3. PWA介绍及快速上手搭建一个PWA应用(opens new window)
  4. Using_Service_Workers(opens new window)
  5. migrate-from-http-to-https(opens new window)