离线应用的优势: 在没有网络的状况下能打开网页。 因为部分缓存的资源直接从本地加载,因此对用户来讲能够加快网页的加载速度,减小服务器压力。
离线应用的核心是离线缓存技术,历史上曾前后出现两种离线缓存技术。webpack
Service Workers是一个在浏览器后台运行的脚本,它的生命周期彻底独立于网页,它没法直接访问DOM。它能够经过postMessage接口发送消息来和UI进程通讯。拦截网络功能是Service Workers的重要功能。经过Service Workers能完成离线缓存,编辑响应,过滤响应等功能。web
目前Chrome,Firefox,Opera都已经全面支持Service Workers。但只有高版本的Android支持移动端的浏览器。,因为Service Workers没法经过注入Polyfill实现兼容,因此在打算使用它前,请先确认本身的网页的运行场景。chrome
注:Polyfill:
垫片,就是帮你加一层东西来解决问题,不光是兼容性问题,pollyfill是个概念举个例子,有些旧浏览器不支持Number.isNaN方法,Polyfill就能够是这样的:浏览器
·if(!Number.isNaN) { Number.isNaN = function(num) { return(num !== num); } }·
啥意思呢,就是假如浏览器没有Number.isNaN方法,那我们就给它添加上去,所谓Polyfill就是这样解决API的兼容问题的。
判断浏览器是否支持Service Workers的最简单方法是经过如下代码:
if(navigator.serviceWorker){alert(true)}缓存
要为网页接入Service Workers,须要在网页加载后注册一个描述Service Workers逻辑的脚本,代码以下:服务器
`if(navigator.serviceWorker) { window.addEventListener('DOMContentLoaded',function(){ navigator.serviceWorker.register('./sw.js') }) }`
一旦这个脚本文件被加载,Service Workers的安装就开始了,在这个脚本被安装到浏览器中后,
就算是用户关闭了当前网页,它仍会存在,也就是第一次打开该网页时,Service Workers的逻辑不会生效。
由于脚本尚未被加载和注册,可是之后再次打开该网页时脚本里的逻辑将会生效。网络
在Chrome中能够经过打开网址chrome://inspect/#service-workers来查看当前浏览器中全部已注册的Service Workers。post
浏览器针对Service Workers有以下机制:
新的Service Workers线程中的activate事件就是清理旧缓存的最佳时间点网站
Service Workers在注册成功后会在其生命周期中派发一些事件,经过监听对应的事件,在特定的时间上作一些事情。ui
在Service Workers脚本中引入了新的关键字self,表明当前的Service Workers实例。
在Service Workers安装成功后会派发出install事件,须要在这个事件中执行缓存资源的逻辑。
用webpack构建接入Service Workers的离线应用时,要解决的问题在于如何生成以前提到的sw.js文件。
而且sw.js文件中的cacheFileList变量,表明须要被缓存文件的URL列表,须要根据输出文件列表所对应的URL来决定。而不是写成静态值。
webpack没有原生功能能够完成以上需求,可使用插件serviceworker-webpack-plugin
·
const ServiceWorkerWebpackPlugin=require('serviceworker-webpack-plugin') new ServiceWorkerWebpackPlugin({ // 自定义的 sw.js 文件所在路径 // ServiceWorkerWebpackPlugin 会把文件列表注入到生成的 sw.js 中 entry: path.join(__dirname, 'sw.js'), }) devServer: { //Service Workers依赖HTTPS,使用DevServer提供的HTTPS功能。 https:true }
·
在目录下新建sw.js文件,手动写手更新缓存里的代码,。
serviceworker-webpack-plugin为了保证灵活性,容许使用都自定义sw.js,构建输出的sw.js文件中会在头部注入一个变量serviceWorkerOption.assets到全局,里面存放着全部须要被缓存的文件的URL列表。
须要将sw.js里的文件列表变量写成动态的
·
var cacheFileList=global.serviceWorkerOption.assets 在main.js代码中注册: if (navigator.serviceWorker) { window.addEventListener('DOMContentLoaded',function() { // 调用 serviceWorker.register 注册,参数 /sw.js 为脚本文件所在的 URL 路径 navigator.serviceWorker.register('sw.js'); }); }
·
**注:使用Service Workers技术须要依赖HTTPS,可使用DevServer提供的HTTPS功能。DevServer会自动生成一份HTTPS证书。**