找回密码
立即注册
搜索
热搜: Java Python Linux Go
发回帖 发新帖

2241

积分

0

好友

319

主题
发表于 前天 07:52 | 查看: 3| 回复: 0

概述

传统网站

采用HTML、CSS、JS等技术编写的网络应用,并通过浏览器进行访问。在用户不访问它时,在用户的设备上没有存在感,只能通过用户打开浏览器并导航到该网站来访问,而且高度依赖于网络连接。

平台专属应用

采用IOS、Android、C++等技术编写的原生应用,只能在专属平台下使用,不能方便的跨平台移植。好处是性能更流畅,支持离线,桌面图标的独立体验等。

跨平台框架

能够用同一套代码同时运行在多个平台(iOS、Android、Web、Windows、Mac 等)上的开发框架。它的核心目标是提高开发效率,减少重复开发,同时尽量保证接近原生的体验和性能。如:React Native,Flutter,uni-app等。

渐进式Web应用

渐进式 web 应用结合了传统网站和平台特定应用的最佳特性。具有网站的优势,包括:

  • 使用标准的 web 平台技术开发的,所以它们可以从单一代码库在多个操作系统和设备类上运行。
  • 可以直接通过浏览器访问。

同时也具有平台特定应用程序的许多优势,包括:

  • 可以从平台的应用商店安装,也可以直接从 web 安装。
  • 设备上得到一个应用图标,与平台特定应用程序一样,用户黏性更强。
  • 具备离线能力,在设备没有网络连接时工作,应用更加可靠。
  • 资源具备缓存能力,使得应用启动速度更快,性能更好。

总结: 渐进式 Web 应用(Progressive Web App,简称 PWA)是一种结合了网页与原生应用优点的新型 Web 应用开发模式。PWA 通过现代 Web 技术提供类似原生应用的体验:可安装、离线使用、后台更新、消息推送等。

PWA基本使用

效果演示

Squoosh 一款开源浏览器中运行的图像压缩工具。

  • web安装
  • 离线访问

同时支持商店安装:

  • 适用于 Android 和 ChromeOS 的 Google Play 商店,使用 Trusted Web Activity。
  • 适用于 iOS、macOS 和 iPadOS 的 Apple App Store,使用 WKWebView 和应用绑定网域。
  • 适用于 Windows 10 和 11 的 Microsoft Store,使用 APPX 软件包。
  • Samsung Galaxy Store,使用 Samsung WebAPK 铸造服务器。
  • 华为 AppGallery,使用适用于 HTML 应用的 QuickApp 容器。

PWA Builder: 支持将你的 PWA 打包为适合各大应用商店提交的安装包格式,例如 Windows Microsoft Store 的 .msix / .appx ,以及通过 TWA 打包后提交至 Google Play Store。还支持 Samsung Store、Meta Quest 平台等。

具备PWA的条件

  • https协议(开发阶段可以localhost)
    • 移动端可以采用模拟器或Fiddler代理本地站点
    • 可通过github actions提供带有https的static page
  • manifest清单
    • 官方扩展名为 .webmanifest ,也可以是为 manifest.json 文件
  • service worker文件
    • 一个特殊的Web Worker文件,可以后台运行
    • 充当代理,拦截浏览器和服务器之间的请求,并处理缓存实现离线访问

mainfest清单

用于告知浏览器您希望 Web 内容以何种方式在操作系统中显示为应用。清单可以包含基本信息(例如应用名称、图标和主题颜色);高级偏好设置(例如所需屏幕方向和应用快捷方式);以及目录元数据(例如屏幕截图)。

{
  "name": "我的 PWA",
  "short_name": "PWA",
  "start_url": "/",
  "display": "standalone",
  "background_color": "#ffffff",
  "theme_color": "#000000",
  "description": "一个简单的 PWA 示例",
  "icons": [
    {
      "src": "icons/test.png",
      "type": "image/png",
      "sizes": "512x512"
    }
  ]
}

PWA应用Manifest配置与显示效果示例

PWA应用四种显示模式对比:全屏、独立应用、最小化UI、浏览器

Service Worker

Service Worker 是渐进式 Web 应用实现离线功能的核心,它运行在浏览器后台的独立线程中,可以拦截和处理网络请求。

浏览器线程模型:UI主线程与Web Worker及Service Worker

为了理解 Service Worker,我们先看一个普通 Web Worker 的例子:

// main.js

// 创建 Worker
const worker = new Worker('worker.js');

// 监听来自 worker 的消息
worker.onmessage = function(event) {
  document.getElementById('result').innerText = '来自 Worker 的消息:' + event.data;
};

// 向 worker 发送消息
function sendMessage() {
  worker.postMessage('你好,Worker!');
}
// worker.js

// 接收主线程的消息
onmessage = function(event) {
  console.log('主线程发来的消息:', event.data);

  // 处理完后,发送消息回主线程
  postMessage('收到你的消息:"'+ event.data +'",你好,主线程!');
};

Service Worker 是一种特殊的 Worker,它充当了网页与应用服务器之间的代理,能够拦截和处理 fetch 请求,这是实现离线缓存和资源控制的关键。

Service Worker在浏览器、页面、服务器和缓存之间的工作流程

使用步骤:

  1. 注册service worker
  2. 添加install事件,注册成功触发,主要用于缓存资料
  3. 添加activate事件,激活的时候触发,主要用于删除旧的资源
  4. 添加fetch事件,主要用于操作缓存或者读取网络资源

自定义安装

当浏览器检测到您的应用可供安装时,就会触发 beforeinstallprompt 事件。您需要实现此事件处理脚本来自定义用户体验。

window.onload = () => {
  if ('serviceWorker' in navigator) {
    navigator.serviceWorker
      .register('./sw.js')
      .then((res) => console.log('service worker registered', res))
      .catch((err) => console.log('service worker not registered', err))
  }

  const btn1 = document.getElementById('btn1')
  btn1.addEventListener('click', () => {
    const deferredPrompt = window.deferredPrompt
    if (!deferredPrompt) {
      console.log('No deferred prompt available.')
      return
    }
    deferredPrompt.prompt()
  })

  // 可安装PWA的事件
  window.addEventListener('beforeinstallprompt', (e) => {
    e.preventDefault()
    window.deferredPrompt = e
  })
}

PWA离线访问

cache storage

cache storage 是 Service Worker 的核心功能之一,它是浏览器提供的一种 在客户端持久化缓存资源(如 HTML、JS、CSS、图片等) 的机制。 在 PWA中,通常使用 cache storage 来离线缓存页面资源,实现离线访问、快速加载等特性。

方法 作用
caches.open(name) 打开或创建一个缓存
cache.add(url) 缓存一个 URL 的请求
cache.addAll([urls]) 批量缓存多个资源
cache.put(request, response) 手动放入缓存(需 clone)
caches.match(request 匹配缓存中的资源
caches.keys() 获取所有缓存名称
caches.delete(name) 删除某个缓存

缓存策略

预缓存(静态资源)

PWA缓存策略:缓存优先流程图

self.addEventListener("fetch", event => {
   event.respondWith(
     caches.match(event.request)
     .then(cachedResponse => {
       // It can update the cache to serve updated content on the next request
         return cachedResponse || fetch(event.request);
     }
   )
  )
});

网络优先(动态缓存)

PWA缓存策略:网络优先流程图

self.addEventListener("fetch", event => {
   event.respondWith(
     fetch(event.request)
     .catch(error => {
       return caches.match(event.request);
     })
   );
});

在重新验证时过时

PWA缓存策略:重新验证时过时流程图

self.addEventListener('fetch', event => {
  event.respondWith(
    caches.match(event.request).then(cachedResponse => {
        const networkFetch = fetch(event.request).then(response => {
          // update the cache with a clone of the network response
          const responseClone = response.clone()
          caches.open(url.searchParams.get('name')).then(cache => {
            cache.put(event.request, responseClone)
          })
          return response
        }).catch(function (reason) {
          console.error('ServiceWorker fetch failed: ', reason)
        })
        // prioritize cached response over network
        return cachedResponse || networkFetch
      }
    )
  )
})

离线通知

  • navigator.onLineonline事件
  • Notifications API

后台同步

  • sync事件
self.addEventListener('sync', (e) => {
  if (e.tag === 'send-email') {
    console.log('send-email success!')
  }
})

PWA框架

Workbox

WorkboxGoogle 推出的一个 PWA(渐进式 Web 应用)工具库,主要用来简化 Service Worker 的编写和管理,让开发者可以更轻松地实现离线缓存、资源预加载、后台同步等功能。

一些常用的模块包括:

  • workbox-routing:当 Service Worker 拦截请求时,此模块会将这些请求路由到提供响应的不同函数;简化 fetch 事件处理脚本的实现。
    
    import { registerRoute } from 'workbox-routing'

registerRoute(
({url}) => url.pathname.startsWith('/api/'),
new NetworkFirst({
cacheName: 'api-cache',
})
)

*   **`workbox-strategies`**:一组运行时缓存策略,用于处理请求响应,例如先缓存并在重新验证时过时:
```js
import { NetworkFirst, CacheFirst, StaleWhileRevalidate } from 'workbox-strategies'
  • workbox-precaching:它是 Service Worker 的 install 事件处理程序中缓存文件的实现(也称为预缓存)。

Workbox生成的预缓存清单代码示例

  • ....

vite-plugin-pwa

vite-plugin-pwa为 Vite 及其生态系统提供 PWA 集成,内部用 Workbox 做 Service Worker 相关的缓存和生成工作。它相当于 “Vite + Workbox 的桥梁”,让你在 Vite 项目里用简单配置就能启用 PWA 功能,而不必手动整合 Workbox 构建流程。

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import { VitePWA } from 'vite-plugin-pwa'

// https://vite.dev/config/
export default defineConfig({
  plugins: [
    vue(),
    VitePWA({
      registerType: 'autoUpdate',
      manifest: {
        name: 'My Awesome App',
        short_name: 'MyApp',
        description: 'My Awesome App description',
        theme_color: '#ffffff',
        icons: [
            {
              src: 'icon-512x512.png',
              sizes: '512x512',
              type: 'image/png',
            },
          ],
        },
    }),
  ],
})

通过合理配置 Service Worker 和利用 Workbox 等工具,你可以显著提升 Web 应用的用户体验。想了解更多前沿的前端技术与实践,欢迎访问云栈社区与开发者们交流探讨。




上一篇:Linux系统文件比较:diff、colordiff、vimdiff等5个实用工具详解
下一篇:Pywinauto Recorder:录制Windows UI操作并生成Python自动化脚本
您需要登录后才可以回帖 登录 | 立即注册

手机版|小黑屋|网站地图|云栈社区 ( 苏ICP备2022046150号-2 )

GMT+8, 2026-1-14 17:10 , Processed in 0.277657 second(s), 40 queries , Gzip On.

Powered by Discuz! X3.5

© 2025-2025 云栈社区.

快速回复 返回顶部 返回列表