中文

一份实现渐进式网络应用(PWA)的综合指南,涵盖核心概念、服务工作线程、清单文件、推送通知以及面向全球受众的最佳实践。

渐进式网络应用:面向全球开发者的完整实现指南

渐进式网络应用(Progressive Web Apps, PWA)代表了网络开发领域的一场范式转移,模糊了传统网站与原生移动应用之间的界限。它们提供了一种以可靠性、可安装性和高参与度为特征的增强型用户体验,是触及全球网络连接和设备能力各异的用户的理想解决方案。

什么是渐进式网络应用?

PWA是利用现代网络标准来提供原生应用般体验的网络应用程序。它们具有以下特点:

与原生应用不同,PWA可以通过搜索引擎被发现,通过URL轻松分享,且无需用户通过应用商店下载。这使其成为企业扩大覆盖面的一种易于访问且经济高效的解决方案。

PWA背后的核心技术

PWA建立在三项核心技术之上:

1. HTTPS

安全至上。PWA必须通过HTTPS提供服务,以防止窃听并确保数据完整性。这是服务工作线程运行的基本要求。

2. 服务工作线程(Service Workers)

服务工作线程是在后台运行的JavaScript文件,与浏览器主线程分离。它们充当Web应用程序与网络之间的代理服务器,可实现以下功能:

服务工作线程生命周期: 理解服务工作线程的生命周期(注册、安装、激活、更新)对于有效的PWA实现至关重要。不正确的管理可能导致缓存问题和意外行为。我们稍后将更详细地介绍更新。

3. Web应用清单(Web App Manifest)

Web应用清单是一个JSON文件,提供有关PWA的元数据,例如:

实现步骤:构建一个简单的PWA

让我们逐步完成构建一个简单PWA的步骤:

第1步:设置HTTPS

确保您的网站通过HTTPS提供服务。您可以从Let's Encrypt获取免费的SSL证书。

第2步:创建Web应用清单(manifest.json)

创建一个名为`manifest.json`的文件,并添加以下代码:


{
  "name": "My Simple PWA",
  "short_name": "PWA",
  "icons": [
    {
      "src": "icon-192x192.png",
      "sizes": "192x192",
      "type": "image/png"
    },
    {
      "src": "icon-512x512.png",
      "sizes": "512x512",
      "type": "image/png"
    }
  ],
  "start_url": "/index.html",
  "display": "standalone",
  "theme_color": "#ffffff",
  "background_color": "#ffffff"
}

将`icon-192x192.png`和`icon-512x512.png`替换为您实际的图标文件。您需要生成各种尺寸的这些图标。像Real Favicon Generator这样的在线工具可以帮助您完成此操作。

第3步:在HTML中链接清单文件

将以下行添加到您的`index.html`文件的``部分:


<link rel="manifest" href="/manifest.json">

第4步:创建服务工作线程(service-worker.js)

创建一个名为`service-worker.js`的文件,并添加以下代码:


const CACHE_NAME = 'my-pwa-cache-v1';
const urlsToCache = [
  '/',
  '/index.html',
  '/style.css',
  '/script.js',
  '/icon-192x192.png',
  '/icon-512x512.png'
];

self.addEventListener('install', function(event) {
  // 执行安装步骤
  event.waitUntil(
    caches.open(CACHE_NAME)
      .then(function(cache) {
        console.log('已打开缓存');
        return cache.addAll(urlsToCache);
      })
  );
});

self.addEventListener('fetch', function(event) {
  event.respondWith(
    caches.match(event.request)
      .then(function(response) {
        // 缓存命中 - 返回响应
        if (response) {
          return response;
        }

        // 重要提示:如果代码执行到这里,说明请求未在缓存中找到。
        return fetch(event.request).then(
          function(response) {
            // 检查我们是否收到了有效的响应
            if(!response || response.status !== 200 || response.type !== 'basic') {
              return response;
            }

            // 重要提示:克隆响应。响应是一个流,
            // 因为我们希望浏览器和缓存都能消费它,
            // 所以需要克隆一份,以便我们有两个独立的副本。
            var responseToCache = response.clone();

            caches.open(CACHE_NAME)
              .then(function(cache) {
                cache.put(event.request, responseToCache);
              });

            return response;
          }
        );
      })
  );
});

self.addEventListener('activate', function(event) {

  var cacheWhitelist = [CACHE_NAME];

  event.waitUntil(
    caches.keys().then(function(cacheNames) {
      return Promise.all(
        cacheNames.map(function(cacheName) {
          if (cacheWhitelist.indexOf(cacheName) === -1) {
            return caches.delete(cacheName);
          }
        })
      );
    })
  );
});

此服务工作线程在安装期间缓存指定文件,并在用户离线或网络缓慢时从缓存中提供这些文件。

第5步:在您的JavaScript中注册服务工作线程

将以下代码添加到您的`script.js`文件中:


if ('serviceWorker' in navigator) {
  window.addEventListener('load', function() {
    navigator.serviceWorker.register('/service-worker.js')
      .then(function(registration) {
        // 注册成功
        console.log('ServiceWorker 注册成功,作用域为: ', registration.scope);
      },
      function(err) {
        // 注册失败 :(
        console.log('ServiceWorker 注册失败: ', err);
      });
  });
}

此代码检查浏览器是否支持服务工作线程,并注册`service-worker.js`文件。

第6步:测试您的PWA

在支持PWA的浏览器(如Chrome、Firefox、Safari)中打开您的网站。打开开发者工具并检查“Application”选项卡,查看服务工作线程是否已正确注册以及清单文件是否已加载。

您现在应该会在浏览器中看到“添加到主屏幕”的提示。点击此提示将在您的设备上安装PWA。

PWA高级功能及注意事项

推送通知

推送通知是重新吸引用户使用您PWA的强大方式。要实现推送通知,您需要:

  1. 获取Push API密钥: 您需要使用像Firebase Cloud Messaging (FCM)或类似的服务来处理推送通知。这需要创建一个账户并获取API密钥。
  2. 订阅用户: 在您的PWA中,您需要请求用户允许接收推送通知,然后将他们订阅到您的推送服务。
  3. 处理推送事件: 在您的服务工作线程中,您需要监听推送事件并向用户显示通知。

示例(简化版 - 使用Firebase):

在您的`service-worker.js`中:


// 导入Firebase库
importScripts('https://www.gstatic.com/firebasejs/9.6.11/firebase-app-compat.js');
importScripts('https://www.gstatic.com/firebasejs/9.6.11/firebase-messaging-compat.js');

// 初始化Firebase
const firebaseConfig = {
  apiKey: "YOUR_API_KEY",
  authDomain: "YOUR_AUTH_DOMAIN",
  projectId: "YOUR_PROJECT_ID",
  storageBucket: "YOUR_STORAGE_BUCKET",
  messagingSenderId: "YOUR_MESSAGING_SENDER_ID",
  appId: "YOUR_APP_ID",
  measurementId: "YOUR_MEASUREMENT_ID"
};

firebase.initializeApp(firebaseConfig);

const messaging = firebase.messaging();

messaging.onBackgroundMessage(function(payload) {
  console.log('[firebase-messaging-sw.js] 收到后台消息 ', payload);
  // 在此处自定义通知
  const notificationTitle = '后台消息标题';
  const notificationOptions = {
    body: '后台消息正文。',
    icon: '/icon-512x512.png'
  };

  self.registration.showNotification(notificationTitle, notificationOptions);
});

重要提示: 请将占位符值替换为您实际的Firebase配置。此示例演示了如何处理后台消息。您需要在主JavaScript代码中实现订阅逻辑。

后台同步

后台同步允许您的PWA即使用户离线也能执行任务。这对于以下场景非常有用:

要使用后台同步,您需要在服务工作线程中注册`sync`事件并处理同步逻辑。

离线支持策略

为您的PWA提供离线支持有多种策略:

最佳策略取决于您应用的具体需求。

PWA更新

服务工作线程的更新是PWA维护的关键部分。当浏览器检测到您的`service-worker.js`文件发生变化(即使是单个字节的更改),它会触发一个更新过程。新的服务工作线程在后台安装,但直到用户下次访问您的PWA或所有由旧服务工作线程控制的现有标签页都关闭后,它才会激活。

您可以在新服务工作线程的`install`事件中调用`self.skipWaiting()`并在`activate`事件中调用`clients.claim()`来强制立即更新。但是,这可能会中断用户体验,因此请谨慎使用。

PWA的SEO注意事项

PWA通常对SEO友好,因为它们本质上是网站。但是,有几点需要注意:

跨浏览器兼容性

虽然PWA基于网络标准,但浏览器支持可能有所不同。在不同的浏览器和设备上测试您的PWA以确保其正常工作非常重要。使用功能检测来在不支持某些功能的浏览器中优雅地降级功能。

调试PWA

由于服务工作线程的异步性,调试PWA可能具有挑战性。使用浏览器的开发者工具来检查服务工作线程的注册、缓存和网络请求。密切关注控制台日志和错误消息。

全球PWA案例

全球众多公司已成功实施PWA。以下是一些不同领域的例子:

结论:拥抱Web的未来

渐进式网络应用为传统网站和原生移动应用提供了一个引人注目的替代方案。它们提供了卓越的用户体验、更高的性能和更强的用户参与度,是企业触达全球受众的宝贵工具。通过理解本指南中概述的核心概念并遵循实施步骤,开发者可以创建可靠、可安装且富有吸引力的PWA,在当今移动优先的世界中获得竞争优势。拥抱Web的未来,从今天开始构建您自己的渐进式网络应用吧!