Progressive Web App, 简称 PWA,是提升 Web App 的体验的一种新方法,能给用户原生应用的体验。

可以发现,现在各大应用都不满足存在于手机浏览器中,或者选择开发安卓和IOS端应用,或者选择寄生在微信小程序这一类平台上;

PWA可以帮助我们的web应用安装在用户应用首页,而不仅是一个浏览器书签。

一个实例:为你的Github Pages应用增加PWA支持

PWA技术借助Service Worker(简称SW)实现,什么是SW,可以理解为浏览器和网络之间的一个中间层,意味着我们可以对请求进行拦截返回自定义结果,也可以缓存网路返回存储本地。添加service-worker.js,我们的PWA应用才真正有了离线能力。

除了SW,还需要增加manifest.json文件,我们应用的配置项就在这里,比如应用标题,应用图标,应用主题色等。。

首先,我们先来完成我们的manifest.json

在线生成模板:https://app-manifest.firebaseapp.com/

manifest各字段解释参考文档: https://lavas.baidu.com/pwa/engage-retain-users/add-to-home-screen/introduction

分享一下我的配置:

{
  "name": "J Blog",
  "short_name": "justforuse's github blog",
  "theme_color": "#010411",
  "background_color": "#0a1b2f",
  "display": "standalone",
  "start_url": "./index.html",
  "icons": [
    {
      "src": "../res/icons/icon-72x72.png",
      "sizes": "72x72",
      "type": "image/png"
    },
    {
      "src": "../res/icons/icon-96x96.png",
      "sizes": "96x96",
      "type": "image/png"
    },
    {
      "src": "../res/icons/icon-128x128.png",
      "sizes": "128x128",
      "type": "image/png"
    },
    {
      "src": "../res/icons/icon-144x144.png",
      "sizes": "144x144",
      "type": "image/png"
    },
    {
      "src": "../res/icons/icon-152x152.png",
      "sizes": "152x152",
      "type": "image/png"
    },
    {
      "src": "../res/icons/icon-192x192.png",
      "sizes": "192x192",
      "type": "image/png"
    },
    {
      "src": "../res/icons/icon-384x384.png",
      "sizes": "384x384",
      "type": "image/png"
    },
    {
      "src": "../res/icons/icon-512x512.png",
      "sizes": "512x512",
      "type": "image/png"
    }
  ],
  "splash_pages": null
}

都是比较随意的配置😂。。

接下来是SW的配置:

if('serviceWorker' in navigator) {
  navigator.serviceWorker
    .register('./sw-v2.js')
    .then((registration) => {
      console.log('Service Worker Registered')
      registration.update()
      console.log('Service Worker Updated')
    })
}

首先是浏览器能力检测,注册SW成功后再执行一遍更新操作。

下面是SW的配置,主要在于SW缓存策略。

const expectedCaches = 'github-blog2'
const staticAssets = [
  '../css/style-zeiwctigkogtvpvj0egasslli0f0ds0fgqxfmddzssy3wjlw6oz5buiywhrb.min.css',
  '../js/script-jolqrkyg17dxydltbpg3rnxckzpon1cph80fa4u74kx2pv6cgo6wwkgyuqqo.min.js'
]

self.addEventListener('install', async e => {
  const cache = await caches.open(expectedCaches)
  await cache.addAll(staticAssets)
  return self.skipWaiting()
})

self.addEventListener('activate', e => {
  self.clients.claim()
  e.waitUntil(
    caches.keys().then(keys => Promise.all(
      keys.map(key => {
        if (!expectedCaches.includes(key)) {
          return caches.delete(key);
        }
      })
    )).then(() => {
      console.log(`${expectedCaches} now ready to handle fetches!`);
    })
  );
})

self.addEventListener('fetch', async e => {
  const req = e.request
  const url = new URL(req.url)
  e.respondWith(networkAndCache(req))
  // if (url.origin === location.origin) {
  //   e.respondWith(cacheFirst(req))
  // } else {
  //   e.respondWith(networkAndCache(req))
  // }
})

async function cacheFirst(req) {
  const cache = await caches.open(expectedCaches)
  const cached = await cache.match(req)
  return cached || fetch(req)
}

async function networkAndCache(req) {
  const cache = await caches.open(expectedCaches)
  try {
    const fresh = await fetch(req)
    await cache.put(req, fresh.clone())
    return fresh
  } catch (e) {
    const cached = await cache.match(req)
    return cached
  }
}

缓存策略有很多种,对于博客类文字类网站,我们这里就粗暴的全部缓存下来,如此,只要我们访问过一篇文章,或一个页面,那么下次即使处于断网状态,我们依旧可以正常阅读,而不是一个断网提示,大大提升了用户体验。

感兴趣可以在本站体验PWA技术,如果你正在使用PC浏览,那么可以手机扫码访问我的主页,注意使用手机Chrome浏览器打开才能看到:

image

如果你正在移动端阅读,不妨使用手机Chrome访问此页面。

在右上角菜单内选择添加到主屏幕即可体验!

觉得作者写得不错?不妨轻击下方按钮~

赏点银子给楼主凑凑买咖啡喝吧
微信
支付宝
扫码打赏,建议金额1-10元

Copied From 畅言