最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • PWA技术

    正文概述 掘金(Spirited Away)   2021-08-25   812

    什么是PWA?

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

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

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

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

    • https服务器或者 http://localhost
    • 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 该应用程序将看起来像一个独立的应用程序,但会有浏览器地址栏。
    
    }
    

    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
    

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

    <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 。
    // 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
    // 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
    // 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
      }
    }
    

    PWA技术


    起源地下载网 » PWA技术

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元