PWA 渐进式 WEB 应用

PWA 渐进式 web 应用

简介

PWA(Progressive Web App,渐进式网页应用)是一种可以提供类似原生应用体验的网页应用。 通过利用最新的 Web 技术特性,实现跨平台兼容性,并且在桌面和移动设备上都能够以全屏或近似原生应用的方式运行。

特性

  • 渐进式:PWA 适用于所有用户,无论他们使用什么浏览器,因为它是以渐进式增强作为核心原则构建的。
  • 响应式:它们的界面自适应各种形态的设备:桌面、手机、平板电脑等。
  • 离线工作:通过 Service Workers 来缓存应用外壳和数据,在没有网络的情况下也可以使用。
  • 感觉像原生应用:PWA 可以添加到设备的主屏幕,发送推送通知,并访问设备功能。
  • 始终更新:由于 Service Worker 的更新过程,PWA始终保持最新。
  • 安全:通过 HTTPS 提供服务,确保应用数据的传输安全。
  • 易找寻:由于是网页应用,所以 PWA 可以通过搜索引擎被发现,与普通网页同样优化 SEO。
  • 可链接:通过 URL 容易分享应用,不需要复杂的安装流程。

关键技术

  • Service Workers: 脚本工作在浏览器后台,独立于网页,可以拦截和处理网络请求,包括缓存或检索资源。
  • Web App Manifest: JSON 文件,描述了个性化起始画面、全屏等展示解决方案以及PWA的外观。
  • Application Shell (App Shell): 基础的 HTML/CSS/JS 架构,负责加载用户界面的速度。
  • IndexedDB 和 Cache API: 缓存资料与结构,实现离线数据的有效管理。

从零创建一个简单的 PWA 渐进式应用

你如果希望使用脚手架搭建一个完整的 PWA 项目,可以尝试使用 Quasar 框架,这也是 Vue 官方推荐的框架。 (www.quasarchs.com/quasar-cli-...

应用目录如下

  • index.html
  • manifest.json
  • service-worker.js
  • icons
    • icon-128x128.png
    • icon-192x192.png
    • icon-256x256.png
    • icon-384x384.png
    • icon-512x512.png

PWA 应用部署与普通网页基本一致,唯一不同的是 PWA 必须使用 https 协议(localhost 除外)。 windows 系统下可以直接下载 nginx,将 html 下的文件替换成项目文件,运行 nginx 即可(nginx.org/en/download...

代码实现

html 复制代码
// index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>PWA渐进式应用</title>
    <link rel="manifest" href="./manifest.json">
</head>
<body>
<h1>PWA渐进式应用</h1>
<script>
    window.addEventListener("load", () => {
      if ('serviceWorker' in navigator) {
        navigator.serviceWorker.register('/service-worker.js')
         .then(function({ installing, waiting, active }) {
           if (installing) console.log("正在安装 Service worker");
           if (waiting) console.log("已安装 Service worker installed");
           if (active) console.log("激活 Service worker");
         })
         .catch(function(err) {
           console.log('Service Worker 注册失败:', err);
         });
      }
    })
</script>
</body>
</html>
json 复制代码
{
  "manifest.json": "配置并引入该文件后即可实现下载,如果需要实现离线使用则需结合 Service Worker",
  "参考地址": "https://developer.mozilla.org/zh-CN/docs/Mozilla/Add-ons/WebExtensions/manifest.json",
  "id": "pwa",
  "name": "pwa",
  "short_name": "pwa",
  "description": "pwa",
  "display": "standalone",
  "start_url": "/",
  "orientation": "portrait",
  "background_color": "#aaa",
  "theme_color": "#fff",
  "icons": [
    {
      "src": "icons/icon-128x128.png",
      "sizes": "128x128",
      "type": "image/png"
    },
    {
      "src": "icons/icon-192x192.png",
      "sizes": "192x192",
      "type": "image/png"
    },
    {
      "src": "icons/icon-256x256.png",
      "sizes": "256x256",
      "type": "image/png"
    },
    {
      "src": "icons/icon-384x384.png",
      "sizes": "384x384",
      "type": "image/png"
    },
    {
      "src": "icons/icon-512x512.png",
      "sizes": "512x512",
      "type": "image/png"
    }
  ]
}
js 复制代码
// service-worker.js
// API 可参考 https://developer.mozilla.org/zh-CN/docs/Web/API/Service_Worker_API

// 定义您想要缓存的文件列表
const CACHE_NAME = 'FIRSTPWA';
const urlsToCache = [
  '/index.html',
  '/manifest.json',
  '/icons/icon-128x128.png',
  '/icons/icon-192x192.png',
  '/icons/icon-256x256.png',
  '/icons/icon-384x384.png',
  '/icons/icon-512x512.png'
];

// 安装 Service Worker 并缓存所有预定义资源
self.addEventListener('install', event => {
  event.waitUntil(
    caches.open(CACHE_NAME)
      .then(cache => {
        console.log('Opened cache');
        return cache.addAll(urlsToCache);
      })
  );
});

// 捕获页面请求,从缓存中提供数据
self.addEventListener('fetch', event => {
  event.respondWith(
    caches.match(event.request)
      .then(response => {
          // 如果缓存命中直接返回缓存内容,否则继续请求
          if (response) {
            return response;
          }
          return fetch(event.request);
        }
      )
  );
});

// 更新缓存
self.addEventListener('activate', event => {
  const cacheWhiteList = [CACHE_NAME];

  event.waitUntil(
    caches.keys().then(cacheNames => {
      return Promise.all(
        cacheNames.map(cacheName => {
          // 删除不在白名单中的缓存
          if (cacheWhiteList.indexOf(cacheName) === -1) {
            return caches.delete(cacheName);
          }
        })
      );
    })
  );
});
相关推荐
zhengxianyi5156 分钟前
vue 首屏加载优化
前端·javascript·vue.js·nginx·gzip·expires·静态文件缓存
老前端的功夫22 分钟前
TypeScript 类型守卫:从编译原理到高级模式
前端·javascript·架构·typescript
未来之窗软件服务32 分钟前
幽冥大陆(七十二) 东方仙盟-在线IP归属地自己封装—东方仙盟练气期
前端·javascript·tcp/ip·仙盟创梦ide·东方仙盟·阿雪技术观
QT 小鲜肉1 小时前
【Linux命令大全】001.文件管理之mc命令(实操篇)
linux·运维·服务器·前端·笔记
土豆_potato1 小时前
AI深度思考到底开不开
前端·aigc
ohyeah1 小时前
React 中的跨层级通信:使用 Context 实现主题切换功能
前端·react.js
winfredzhang1 小时前
打造专属桌面时钟:纯HTML实现的全功能动态时钟
前端·html·农历·生肖·周次
哥本哈士奇2 小时前
使用Gradio构建AI前端 - RAG的QA模块
前端·人工智能·状态模式
扶我起来还能学_2 小时前
Vue3 proxy 数据响应式的简单实现
前端·javascript·vue
Dragon Wu2 小时前
前端项目架构 项目格式化规范篇
前端·javascript·react.js·前端框架