Everything

为网站增加PWA支持实现原生应用体验

by Mion, 2021-08-22


前些时间用Web写了一个简单的物联网控制程序,本来想是不是需要打包成APP然后发布。后来发现了PWA能够直接将网页添加到各种设备中来实现原生应用的功能如发送通知、离线查看、渐进式加载等。PWA可以将各类网页都“打包”成原生应用,包括单一网页或者Typecho博客,以下,将会拿本博客举例实现PWA的简单应用。

什么是PWA(渐进式 Web 应用)


PWALOGO

PWA(Progressive Web Apps,渐进式 Web 应用)运用现代的 Web API 以及传统的渐进式增强策略来创建跨平台 Web 应用程序。这些应用无处不在、功能丰富,使其具有与原生应用相同的用户体验优势。PWA 是可被发现、易安装、可链接、独立于网络、渐进式、可重用、响应性和安全的。

简单理解,PWA可以将Web应用转化成能够在多平台设备上使用的原生应用程序并且具有和原生应用接近的交互体验,无需下载直接安装。

注意:PWA并不是一种单独的技术,而是多项Web技术集成的Web App,其核心技术包括App ManifestService WorkerWeb Push等。

快速为网站配置PWA

以下将简单阐述如何快速为网站添加PWA支持,内容较为简单且没有发挥出PWA的全部功能,若需要更深入研究请见文末的拓展阅读。

配置HTTPS

Service Worker必须运行在HTTPS或本地环境下,所以开启PWA的前提是配置好站点的HTTPS!!!在这里不再赘述。

制作应用图片

PWA需要为APP注册一个ICON,这里使用和网站favicon相同的图标,并且推荐将图片的分辨率保证在256x256以上!

配置Manifest

Manifest是一份用JSON记录网站信息的清单,其中包含了应用的标题、图标的大小与路径、加载页的背景颜色等,只有编写了这份清单浏览器才能正确处理Web App信息。在编写Manifest时会发现有不同拓展名,如manifest.webappmanifest.json,但是在W3C规范中规定了其标准拓展名应为.webmanifest以下是我编写的一份Manifest示例:

{
  "background_color": "#fff", //Web App启动时的背景颜色,可以使用预设的一些颜色名字如red,blue等,或者直接使用HEX颜色值如#66ccff(天依蓝)
  "description": "Describe your site.", //Web App的描述,这里的内容将会在安装时展现
  "display": "fullscreen", //Web App展示的方式,可选的值有fullscreen,standalone,minimal-ui,browser等,具体含义请见文末拓展阅读
  "icons": [
    {
      "src": "icon.png",
      "sizes": "192x192",
      "type": "image/png"
    }
  ], //这里举例了应用图片的配置,可以配置多个图标!
  "name": "Awesome fox pictures", //应用的名称,在安装时展示
  "short_name": "Foxes", //缩略名,一般在添加到桌面之后会展示这个名字
  "start_url": "/" //启动后进入的
}

然后将本文件保存为manifest.webmanifest并放置在网站根目录,并在网站<head>标签内添加以下内容:

<link rel="manifest" href="manifest.webmanifest">

Safari浏览器对PWA支持并不完善,如果需要正确的展示PWA应用,需要将以下代码根据实际情况调整后添加在<head>标签内:

<link rel="shortcut icon" href="favicon.ico">
<link rel="shortcut icon" href="src to icon" type="image/x-icon" />
 <link rel="apple-touch-icon" href="src to icon" />
 <meta name="apple-mobile-web-app-capable" content="yes">
 <meta name="apple-mobile-web-app-title" content="Web App Name">

注册Service Worker实现A2HS

我们需要Service Worker来处理安装A2HS(Add to Home screen)与缓存事件,通常情况下A2HS事件会由浏览器自行处理,但是某些情况下我们想要自己控制这个行为来引导用户安装PWA应用。

首先编写index.js,这部分内容也可以直接编写在网页的<script>标签中。

// 注册Service Worker来使网站离线工作

if ('serviceWorker' in navigator) {
  navigator.serviceWorker
    .register('/sw.js') //Service Worker文件路径
    .then(() => { console.log('Service Worker Registered'); });
}

// 提醒用户安装PWA应用,如果您不想这样,可以直接使用showInstallPromotion();

let deferredPrompt;
const addBtn = document.querySelector('.add-button');
addBtn.style.display = 'none';

window.addEventListener('beforeinstallprompt', (e) => {
  // 防止Chrome 67以前版本的浏览器出现此提醒
  e.preventDefault(); //阻止自动提示,若想将A2HS的控制权交给浏览器则请注释
  deferredPrompt = e;
  // 显示安装提醒按钮
  addBtn.style.display = 'inline';

  addBtn.addEventListener('click', () => {
    // 隐藏提示按钮
    addBtn.style.display = 'none';
    // 显示安装提示
    deferredPrompt.prompt();
    deferredPrompt.userChoice.then((choiceResult) => {
      if (choiceResult.outcome === 'accepted') {
        console.log('User accepted the A2HS prompt');
      } else {
        console.log('User dismissed the A2HS prompt');
      }
      deferredPrompt = null;
    });
  });
});

此时我们需要在<body>内有一个用来提示安装的按钮,示例代码如下:

<button class="add-button">将网页添加到桌面</button>

接下来是Service Worker的代码,将其命名为sw.js并保存。

self.addEventListener('install', (e) => {
  e.waitUntil(
    caches.open('store').then((cache) => cache.addAll([
      '/',
      '/index.html', //需要缓存的静态资源
    ])),
  );
});

self.addEventListener('fetch', (e) => {
  console.log(e.request.url);
  e.respondWith(
    caches.match(e.request).then((response) => response || fetch(e.request)),
  );
});
//处理fetch事件

成果展示


安装提示

展示

拓展阅读

Progressive Web Apps

Add a web app manifest

让 PWA 易于安装 - 渐进式 Web 应用(PWA) | MDN

Add to Home screen

添加到主屏幕 - 渐进式 Web 应用(PWA) | MDN

渐进式 Web 应用(PWA)| MDN

《PWA 应用实战》

Web app manifests

作者: Mion

2022 © Mion'Blog & Theme By xingr