PWA技术

简介: PWA技术

什么是PWA?


PWA 指的是使用指定技术和标准模式来开发的 Web 应用,这同时赋予它们 Web 应用和原生应用的特性。


我的简单理解就是:通过一些新技术,来增强web app的用户交互体验。


你可以通过安装应用使得它在离线的状态下也可以运行;相较于使用浏览器访问,用户也更喜欢通过点击主页上的图标来访问它们喜爱的应用。


一个标准的PWA程序,必须包含3个部分:



  • manifest.json


  • service worker


PWA的优势


  • 渐进式 - 适用于所有浏览器,因为它是以渐进式增强作为宗旨开发的。


  • 流畅 - 能够借助 Service Worker 在离线或者网络较差的情况下正常访问。


  • 可安装 - 用户可以添加常用的 webapp 到桌面,免去去应用商店下载的麻烦。


  • 原生体验:可以和app一样,拥有首屏加载动画,可以隐藏地址栏等沉浸式体验。


  • 粘性 - 通过推送离线通知等,可以让用户回流。


PWA的核心内容


web app manifest


他是一个json文件,manifest 的目的是将Web应用程序安装到设备的主屏幕,为用户提供更快的访问和更丰富的体验。


配置一些添加到做面上的一些信息。


{
  "name": "zh-llm-app",
  "shor_name": "zl",
  "start_url": "index.html",
  "icons": [
    {
      "sizes": "添加到桌面上的图标宽高",
      "src": "添加到桌面上的图标",
      "type": "image/类型"
    }
  ],
  "background_color": "应用的背景",
  "theme_color": "导航背景",
  "display": "standalone"
  //fullscreen 全屏显示, 所有可用的显示区域都被使用, 并且不显示状态栏。
  //standalone 让这个应用看起来像一个独立的应用程序,包括具有不同的窗口,在应用程序启动器中拥有自己的图标等。
  // minimal-ui 该应用程序将看起来像一个独立的应用程序,但会有浏览器地址栏。
}


具体内容请访问mdn:developer.mozilla.org/zh-CN/docs/…


sevice worker


主要用来做持久的离线缓存(这个需要配合caches来使用)。Service Worker 是浏览器和网络之间的虚拟代理。Service Worker 运行在一个与页面 JavaScript 主线程独立的线程上,并且无权访问 DOM 结构。控制网络请求、修改网络请求、返回缓存的自定义响应,或者合成响应。是一种特殊的web worker


什么是web worker


Web Worker 是脱离在主线程之外的,将一些复杂的耗时的活交给它干完成后通过 postMessage 方法告诉主线程。Web worker是一个独立的运行环境,不能操作DOM和BOM。


一个事例: 计算大量的累加。由于比较耗时,所以放在js主线程之外去做。


// work.js
    let total = 0;
    for (let i = 0; i < 100000000; i++) {
      total += i;
    }
    self.postMessage({
      total
    })


console.log("start")
    const worker = new Worker("./work.js");
    worker.addEventListener("message", e => {
      console.log("e", e.data)
    })
    console.log("end")
    // 执行顺序:start end 打印e


具体的web worker的用法,请访问mdn: developer.mozilla.org/zh-CN/docs/…


现在我们就来看看强大的sevice worker如何工作的吧


在window.onload中注册service worker , 防止与其他资源竞争。


注册service worker navigator.serviceWorker.register(‘./sw.js’) ,返回一个promise对象。


注册完成后,sw.js 文件会自动下载、安装,然后激活。


<script>
    window.onload = function() {
      if ('serviceWorker' in navigator) {
        navigator.serviceWorker.register('./sw.js')
      }
    }
    /* 
      当权限为default时,我们需要获取用户的授权。
    */
    if (Notification.permission === 'default') {
      Notification.requestPermission()
    }
    if (!navigator.onLine) {
      new Notification('提示', { body: '你当前没有网络,你访问的是缓存中的内容!' })
    }
    // offline: 断线
    window.addEventListener('online', () => {
      new Notification('提示', {
        body: '网路已连接,请刷新访问最新的数据!'
      })
    })
</script>


Service worker生命周期事件


  • install 。


install 的监听函数中, 我们可以初始化缓存并添加离线应用时所需的文件。


// sw.js
// 定义一个cache_name变量,由于确定后续缓存文件的更新。
const CACHE_NAME = 'cache_v1';
// 监听install事件,用于缓存静态文件
self.addEventListener("install", async (e) => {
  console.log("install==========")
  // 定义一个缓存对象。
  const cache = await caches.open(CACHE_NAME);
  // 向cacheStorage中缓存文件
  await cache.addAll(['/', './01.jpg', './manifest.json', './index.css'])
  // 当上述代码执行完后,才跳出此service-worker的等待。
  await self.skipWaiting()
})


  • activate


该事件会在service worker激活的时候触发,主要用于删除旧的资源。

service worker激活后,会在下一次刷新页面的时候生效,可以通过self.clients.claim()立即获取控制权。


// sw.js
// 用于删除过期的缓存
self.addEventListener("activate", async e => {
  console.log("activate========")
  // 获取当前所有的缓存对象
  const keys = await caches.keys();
  keys.forEach(item => {
    if (item !== CACHE_NAME) {
      // 删除过期缓存
      caches.delete(item)
    }
  })
  await self.clients.claim();
})


  • fetch


它在每次应用发起 HTTP 请求的时候被触发。这个事件对我们来说非常有用,它允许我们拦截请求并对请求作出自定义的响应。


在这里我们可以选择网路优先还是缓存优先。


// sw.js
self.addEventListener('fetch', e => {
  // 1. 只缓存同源的内容
  const req = e.request
  const url = new URL(req.url)
  if (url.origin !== self.origin) {
    return
  }
  if (req.url.includes('/api')) {
  // 这里是请求接口
    e.respondWith(networkFirst(req))
  } else {
  // 这里是请求静态文件,在缓存中取。
    e.respondWith(cacheFirst(req))
  }
})
// cache优先, 一般适用于静态资源
async function cacheFirst(req) {
  const cache = await caches.open(CACHE_NAME)
  const cached = await cache.match(req)
  // 如果从缓存中得到了
  if (cached) {
    return cached
  } else {
  // 这里的fetch可以接受一个url,还可以是request对象。
    const data = await fetch(req)
    return data
  }
}
// 网络优先的数据,如果我们获取到了数据,应该往缓存中存一份
async function networkFirst(req) {
  const cache = await caches.open(CACHE_NAME)
  try {
    const data = await fetch(req)
    // 网络优先,获取到的数据,应该再次更新到缓存
    // 把响应的备份存储到缓存中
    cache.put(req, data.clone())
    return data
  } catch (e) {
    const cached = await cache.match(req)
    return cached
  }
}


网络异常,图片无法展示
|


具体请访问mdn: developer.mozilla.org/zh-CN/docs/…


相关文章
|
5月前
|
Rust 前端开发 开发者
探索前端技术发展趋势:从WebAssembly到PWA
【2月更文挑战第10天】随着互联网的快速发展,前端技术也在不断演进。本文将从WebAssembly和渐进式Web应用(PWA)两个方面探讨前端技术的发展趋势,分析它们对于前端开发的影响和未来发展潜力。
|
JSON 缓存 搜索推荐
Progressive Web Apps(PWA):未来网络体验的崭新纪元
在当今数字化的世界中,Progressive Web Apps(PWA)已经成为了Web开发的一项重要趋势。PWA是一种结合了Web和原生应用程序优点的新型Web应用,它们提供了高性能、离线访问和优秀的用户体验。本博客将深入探讨PWA的概念、特点以及为什么它们对未来网络体验如此重要。
182 0
|
供应链 JavaScript 前端开发
业界三款主流的 PWA Storefront 概述
业界三款主流的 PWA Storefront 概述
|
3月前
|
缓存 前端开发 JavaScript
PWA实战:从零构建高性能渐进式应用
【7月更文第28天】渐进式Web应用(PWA)是一种使用现代Web技术构建的应用程序,它具有原生应用程序的功能,例如离线访问、推送通知和安装到主屏幕的能力。本文将引导您从零开始构建一个高性能的PWA,并涵盖关键技术点,如Service Workers、缓存策略、离线支持和性能优化。
123 3
|
13天前
|
前端开发 JavaScript API
前端技术新趋势:PWA与Jamstack的融合探索
【10月更文挑战第4天】前端技术新趋势:PWA与Jamstack的融合探索
24 4
|
3月前
|
缓存 Shell API
PWA与原生应用:性能与用户体验的深度对比
【7月更文第28天】随着Web技术的进步,渐进式Web应用(Progressive Web Apps, PWA)已成为一种越来越受欢迎的选择,它结合了Web和原生应用的优点。尽管如此,原生应用仍然占据着移动应用市场的主导地位。本文将深入探讨PWA与原生应用之间的性能和用户体验方面的差异,并通过一些实际代码示例来展示如何构建高性能的PWA。
133 1
|
传感器 Web App开发 缓存
PWA 技术诞生的前世今生漫谈
PWA 技术诞生的前世今生漫谈
|
5月前
|
缓存 API 定位技术
PWA:革新移动网页体验的技术之力
【4月更文挑战第23天】PWA(Progressive Web Apps)技术革新移动网页体验,结合Web开放性和原生应用性能,提供接近原生应用的体验。通过Service Workers、Manifest和HTTPS,实现离线访问、推送通知等功能。PWA具有跨平台兼容、无需安装、快速加载等优势。构建PWA需关注HTTPS通信、Manifest配置、Service Workers管理和性能优化。遵循响应式设计、清晰交互等最佳实践,不断提升用户体验。PWA将持续推动移动应用领域创新。
|
5月前
|
编解码 前端开发 JavaScript
前端发展趋势:WebAssembly、PWA 和响应式设计
前端发展趋势:WebAssembly、PWA 和响应式设计
|
5月前
|
Web App开发 JavaScript 前端开发
渐进式网页应用(PWA)
【1月更文挑战第1天】