Progressive Web Apps (PWA)是Google在移动时代力推的一个提高webapp性能和体验解决方案,官方列举了几大新特色:css
— 链接无关性 - 可以借助 Service Worker 在离线或者网络较差的状况下正常访问html
我的理解核心目的加强WebApp的体验:git
Service Worker是实现PWA应用最重要的一项技术,是一个在用户没有打开网页没有交互行为时运行在浏览器后台进程中的脚本,提供管理资源缓存、拦截资源、消息推送通知请求等功能。
阅读下面内容前你须要作一些预备知识github
Service_Worker_API
Cache_API
首先咱们须要检查浏览器是否支持service workerweb
if ('serviceWorker' in navigator) { navigator.serviceWorker .register('./service-worker.js') .then(function() { console.log('Service Worker Registered'); }); }
注意service-worker.js文件应用的根文件夹内,由于服务工做线程的做用域由该文件所在的目录定义。
在service worker中,咱们经过cache相关的api缓存静态资源或者请求数据,从而达到应用秒开的效果。shell
首先,咱们在service worker被install以后,经过 caches.open() 打开一个指定key的缓存。缓存key可以让咱们对资源进行版本控制。实际使用时,咱们通常会将数据与 App Shell(静态资源) 分开,以便咱们能轻松地更新某个数据,而不会影响其余数据。json
缓存打开后,咱们即可调用 cache.addAll(),这个带有网址列表参数的方法随即从服务器获取文件,并将响应添加到缓存内。遗憾的是,cache.addAll() 具备原子性,若是任何一个文件失败,整个缓存步骤也将失败!api
var cacheName = 'cache-1'; var filesToCache = [ '/scripts/app.js', '/styles/inline.css', '/images/clear.png', ]; self.addEventListener('install', function(e) { console.log('[ServiceWorker] Install'); e.waitUntil( caches.open(cacheName).then(function(cache) { console.log('[ServiceWorker] Caching app shell'); return cache.addAll(filesToCache); }) ); });
从新加载页面以后,打开 DevTools,转至 Application 面板的 Cache Storage 窗格,能够查看全部被缓存的资源浏览器
上面提到缓存分为静态资源和请求数据。在访问页面时,咱们拦截发送的请求,并将其响应存储在缓存内。对于静态资源咱们再次访问页面时,若是资源版本没有修改,就能够直接命中缓存方便。而对于请求的数据咱们采用缓存优先于网络策略,咱们指望网络响应成为“可信来源”,始终可以为咱们提供最新信息。在第一次访问页面时,缓存数据解决了webapp内容区域空窗的问题,让用户体验更好。缓存
self.addEventListener('fetch', function(e) { // console.log('[Service Worker] Fetch', e.request.url); var dataUrl = 'https://query.yahooapis.com/v1/public/yql'; if (e.request.url.indexOf(dataUrl) > -1) { /* * When the request URL contains dataUrl, the app is asking for fresh * weather data. In this case, the service worker always goes to the * network and then caches the response. This is called the "Cache then * network" strategy: * https://jakearchibald.com/2014/offline-cookbook/#cache-then-network */ e.respondWith( caches.open(dataCacheName).then(function(cache) { console.log('dataCacheName', cache) return fetch(e.request).then(function(response){ cache.put(e.request.url, response.clone()); return response; }); }) ); } else { /* * The app is asking for app shell files. In this scenario the app uses the * "Cache, falling back to the network" offline strategy: * https://jakearchibald.com/2014/offline-cookbook/#cache-falling-back-to-network */ e.respondWith( caches.match(e.request).then(function(response) { return response || fetch(e.request); }) ); } });
对于缓存,它是一把双刃剑,它带来了出色体验,也会面临一些新的难题-缓存更新。在生产环境中,google官方推荐sw-precache生成service worker代码,它内置了缓存更新策略,能够确保将资源过时的请求发送到服务器。
App Shell 是启动PWA应用用户界面所需的最小的资源(HTML、CSS 和 JavaScript)。Shell文件一旦经过网络完成加载,就会经过service workder保存到缓存中。之后每当用户打开应用时,就会自动从本地的缓存中打开Shell文件,确保加载速度很是快。
PWA应用容许用户将轻松得将使用的webapp添加到系统的主屏幕,并且这个功能实现十分简单,浏览器内核帮咱们处理了大量复杂的内部工做,咱们只须要在应用根目录下添加一个应用清单文件manifest.json
供参考的模板
{ "name": "Weather", "short_name": "Weather", "icons": [{ "src": "images/icons/icon-128x128.png", "sizes": "128x128", "type": "image/png" }, { "src": "images/icons/icon-144x144.png", "sizes": "144x144", "type": "image/png" }, { "src": "images/icons/icon-152x152.png", "sizes": "152x152", "type": "image/png" }, { "src": "images/icons/icon-192x192.png", "sizes": "192x192", "type": "image/png" }, { "src": "images/icons/icon-256x256.png", "sizes": "256x256", "type": "image/png" }], "start_url": "/index.html", "display": "standalone", "background_color": "#3E4EB8", "theme_color": "#2F3BA2" }
manifest.json能够描述webapp不一样的展示形式
当咱们提PWA应用兼容性问题时,咱们说的实际上是PWA背后的新特性在各大浏览器厂商的支持程度。
在当前时间点来看这个问题,整体仍是抱乐观态度,国内外的大部分浏览器都已经实现PWA必需的关键技术,全部剩余技术目前都处于开发阶段。
对于最大的绊脚石safari,苹果也2018年1月宣布将在 iOS 11.3 和 macOS 10.13.4 版本上正式增长对 Service Worker 的支持,同时还支持了添加到桌面(Web App Manfiest)。
兼容性参考,数据每两周更新一次
行业内flipboard、flipkart、阿里巴巴国际站、饿了么都已经落地PWA,百度开源了基于Vue的PWA解决方案lavas。PWA应用正在将迎来春天,成为趋势。对PWA感兴趣的同窗能够一块儿探讨学习