《高阶前端指北》之深入中出 PWA(5分钟搞定)

3,832 阅读4分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第2天,点击查看活动详情

什么是PWA

PWA 的英文全称是 Progressive Web Apps,渐进式 Web 应用, 运用现代的 Web API 以及传统的渐进式增强策略来创建跨平台 Web 应用程序,为网页提供 App 般使用体验的一系列方案。

PWA 实际上仍是网页,只不过它添加了App Manifest 和 Service Worker 来实现 PWA 的安装和离线等功能。

优势

  • 无需安装
  • 快捷方式添加到桌面上,点击主屏幕图标可以实现启动动画以及隐藏地址栏
  • 离线缓存功能,即使用户手机没有网络,依然可以使用一些离线功能
  • 消息推送
  • 内容可以通过搜索引擎发现
  • 使用 URL 分享
  • 在任何具有屏幕和浏览器的设备上可以正常使用

核心

Application Manifest

即通过一个清单文件向浏览器暴露 web 应用的元数据,包括名称、icon 的 URL 等,以备浏览器使用,比如在添加至主屏或推送通知时暴露给操作系统,从而增强 web 应用与操作系统的集成能力。

image.png 配置参数

{
  "lang": "en",
  "dir": "ltr",
  "name": "uuoa",
  "short_name": "Racer3K",
  "icons": [{
    "src": "icon/lowres.webp",
    "sizes": "64x64",
    "type": "image/webp"
  }, {
    "src": "icon/lowres.png",
    "sizes": "64x64"
  }, {
    "src": "icon/hd_hi",
    "sizes": "128x128"
  }],
  "scope": "/",
  "id": "superracer",
  "start_url": "/index.html",
  "display": "fullscreen",
  "orientation": "landscape",
  "theme_color": "aliceblue",
  "background_color": "red"
}

详细字段介绍:

  • name: 网站应用的全名。
  • short_name: 用户主屏幕上的应用名字。
  • description: 应用的描述。
  • icons: 主屏幕的图标。
  • start_url: 启动应用的网址。
  • display: 应用的显示方式;可以是全屏,独立,最小UI或者浏览器。
  • theme_color: 浏览器的地址栏等 UI 元素的颜色。
  • background_color: 背景色,用于安装程序时和显示启动画面时。

Service Worker

是一个可编程的 Web Worker,它就像一个位于浏览器与网络之间的客户端代理,可以拦截、处理、响应流经的 HTTP 请求;配合随之引入 Cache Storage API,可以自由管理 HTTP 请求文件粒度的缓存,这使得 Service Worker 可以从缓存中向 web 应用提供资源,即使是在离线的环境下。 image.png

Service Worker 的注意事项:

  • Service worker 运行在 worker 上下文(self) –> 不能访问 DOM(这里其实和 Web Worker 是一样的);
  • 它设计为完全异步,同步 API(如 XHR 和 localStorage)不能在 service worker 中使用;
  • 出于安全考量,Service workers 只能由 HTTPS 承载;
  • 某些浏览器的用户隐私模式,Service Worker 不可用;
  • 其生命周期与页面无关(关联页面未关闭时,它也可以退出,没有关联页面时,它也可以启动)。 运行机制

注册也很简单,一般取名为 service-worker.js

// 首先检查浏览器是否支持 Service Worker
if ('serviceWorker' in navigator) {
  navigator.serviceWorker
    .register('/sw/service-worker.js')
    .then(function(registration) {
      console.log(registration);
    })
    .catch(function(err) {
      console.log(err);
    });
}

同样,概念类的不过多累述,提供官方地址

使用

1.在根目录下index.html中引用上述文件

<link rel="manifest" href="/manifest.json">
<script>
  // PWA
  window.addEventListener('load', function () {
    if ('serviceWorker' in navigator) {
      navigator.serviceWorker.register('/service-worker.js');
    }
  });
</script>

2,通过CSS判断PWA环境,修改导航栏样式

  /* pwa样式兼容 */
  @media (min-width: 737px) and (display-mode: standalone) {
    body::after {
      content: '';
      display: block;
      position: fixed;
      top: 0px;
      left: 0px;
      right: 0px;
      height: 1px;
      background: rgb(218, 225, 233);
      z-index: 10000;
    }
  }
</style>

3,PWA环境判断

function isPwa() {     
  var displayModes = ["fullscreen", "standalone", "minimal-ui"];     
  return displayModes.some((displayMode) => window.matchMedia('(display-mode: ' + displayMode + ')').matches); 
}

Webpack集成PWA

const webpack = require('webpack');
const WebpackPwaManifest = require("webpack-pwa-manifest");

module.exports = {
  plugins: [
    new WebpackPwaManifest({
      name: "DEMO",
      short_name: "DEMO",
      background_color: "#fff",
      theme_color: "#fff",
      start_url: "/",
      publicPath: "/static/",
      display: "standalone",
      icons: [{
        src: path.resolve("public/icon-512.png"),
        // For Chrome, you must provide at least a 192x192 pixel icon, and a 512x512 pixel icon.
        // If only those two icon sizes are provided, Chrome will automatically scale the icons
        // to fit the device. If you'd prefer to scale your own icons, and adjust them for
        // pixel-perfection, provide icons in increments of 48dp.
        sizes: [512, 192],
        purpose: "any maskable",
      }, ]
  ]
}

总结

最近在写一个小应用,突然想起多年前的一阵热风PWA,不知道现在过的怎样。到案例库看了一下,着实惊艳,一些应用设计的堪比桌面软件,体验丝滑。 接下来,准备在所有的效率工程应用中集成这个能力。还有开源的PWA生成器可以体验:www.pwabuilder.com/?from=madew…

最近,准备写书,但是工作比较繁忙,章节的也有一章没一章更新着,正好这次活动强迫自己,每天从书里摘除一些内容坚持创作。

闲着没事的朋友可以我,点个赞评个论收个藏关个注。