文档章节

从webWorker到serviceWorker

ouven
 ouven
发布于 2015/12/09 11:23
字数 3120
阅读 1297
收藏 4
点赞 0
评论 0

从webWorker到serviceWorker

http://www.w3.org/TR/2014/WD-service-workers-20140508/#introduction 下面将从webWorker、serviceWorker和为什么使用serviceWorker三个方面进行讨论

一、Web worker

要了解serviceworker,先的认识下webworker,也可以了解一下二者的共同点,并予以区分。

Web Workers 是 现代浏览器 提供的一个javascript多线程解决方案,我们可以将一些大计算量的代码交由web Worker运行。JavaScript语言执行采用的是单线程模型,也就是说,所有任务排成一个队列,一次只能做一件事。但是有了webworker后就不一样了。

(1) 兼容性

支持的浏览器包括IE10、Firefox (从3.6版本开始)、Safari (从4.0版本开始)、Chrome 和 Opera 11+,但是手机浏览器还不支持。

(2) 基础API

构造一个webworker:new Worker(path) ,返回一个Worker对象。

返回的对象

onerror:用于worker出错处理 onmessage:用户主线程和worker线程传递数据,可以使字符串数字或对象,但是safari浏览器不支持对象,需要用stringify和parse转化。当然和可以使用addeventListener("message",function(){}); 煮个栗子:(例子代码见附件)

输出

如何结束worker: 主页面worker.terminate();或worker自销毁self.close();或者关闭页面

sharedworker: 除了webWorker,还有另一类sharedworker支持多个浏览器窗口共享同一个worker,单个页面关闭,worker并不结束,需关闭浏览器。但这里不做深入讨论

importScripts: worker内部引用文件的方法,可以将worker分成不同的多个文件,然后使用importScripts加载,并可以实现文件的动态加载。就像html中使用script标签引入js一样。 global worker上下文: 前面提到在worker中不能使用window对象和docuemnt对象,是因为一个webworker拥有一个独立的运行环境Workerglobalscope并和浏览器的环境独立,Workerglobalscope环境包括:

  • JavaScript的全局对象:JSON、Date()、Array *self自身引用 *location对象,但是其属性都是只读的,改了也影响不到调用者 *navigator对象,但修改了部分属性 *setTimeout()、setInterval()及其对应清除方法 *addEventListener()、removeEventListener() http://dev.w3.org/html5/workers/#dedicatedworkerglobalscope

(3) 局限性

1.同源限制。webworker不能跨域加载JS 2.DOM限制。worker内代码不能访问dom,原因是worker有自己独立的global worker环境,不是浏览器window,所以alert(),dom等操作无法进行 3.文件限制。子线程无法读取本地文件,即worker只能加载网络文件。 4.不是每个浏览器都支持这个新特性,且各个浏览器对Worker的实现不大一致,例如FF里允许worker中创建新的worker,而Chrome中就不行

二、ServiceWorker

Service Worker是基于Web Worker的事件驱动的,他们执行的机制都是新开一个线程去处理一些额外的,以前不能直接处理的任务。对于Web Worker,我们可以使用它来进行复杂的计算,因为它并不阻塞浏览器主线程的渲染。而Service Worker,我们可以用它来进行本地缓存或请求转发,相当于一个浏览器端本地的proxy。

例如使用Service Worker来进行缓存,是用javascript代码来拦截浏览器的http请求,并设置缓存的文件,直接返回,不经过web服务器,然后,我们就可以开发基于浏览器的离线应用。这使得我们的web应用减少对网络的依赖。 如果我们使用了Service Worker做缓存,浏览器http请求会先经过Service Worker,通过url mapping去匹配,如果匹配到了,则使用缓存数据,如果匹配失败,则继续执行你指定的动作。一般情况下,匹配失败则让页面显示“网页无法打开”。

上面是Service Worker的一个基本使用场景,当然还有更多,先了解一下serviceWorker。

(1) 兼容性

https://jakearchibald.github.io/isserviceworkerready/ (目前API支持现状,有兴趣的自己看,反正就是基本上只有chrome测试版和FF nightly版本支持)

chrome版本下要支持还要开启serviceWorker支持,打开chrome://flags/

此外特定的API还需要特定的环境:

此外还有开启实验平台、使用chrome canary测试版本,这个确实比较麻烦。但是实际上使用最新的canary版本也无法完全支持草案中的所有API,实验时使用的chrome稳定37版本和canary 40版本环境。可能后面新版本又会修改。

(2) serviceWorker介绍

ServiceWorkerGlobalScope部分作用域定义如下

可以看出,这个webworker的scope有点不一样,但是也有些共同部分 scriptCache:worker的文件一旦注册使用,会被缓存到浏览器中,需要手动清理掉,例如: ,注册使用了sw.js,sw.js修改后必须清理缓存后才生效

client:返回serviceworkClients对象

scope:返回serviceworker的url路径数组,并和serviceworker的注册事件关联,一旦注册,serviceworker的路径就会在scope中。

注册与销毁:register&unregister,register执行后返回一个Promise对象,所以要支持serviceWorker浏览器必须先支持Promise
事件Event:
*install:worker使用register注册时会触发install事件
*activate:worker使用register注册时也会触发activate事件
*fetch:浏览器发送请求时会产生fetch事件,此时可以调用一个请求响应的对象,或者可以使用responseWith来指定请求返回内容
*responseWith:responseWith必须指定一个相应内容,否则会发生触发error event,请求成功后会获得一个正确的url。
*waitUtil:waitUtil可以为install指定时间延时,让install的动作延后执行。
*replace:install事件执行完成后会指定replace
onmessage:主线程与worker之间调用传递数据的通道
postMessage:同webworkers类似,用于进行数据传递,canary版本不支持。stable反而支持

...还有一些感觉不常用的就不列出了

(3) 煮个栗子

现在要使用serviceWorkers实现请求转发,详见代码中的的 urlredirect/下代码

sw.js(serviceworker)中实现了对9.url.cn的请求全部转发请求返回一张图片,即把bg-logo.png换成另一张220尺寸的图片。 更多栗子见附件所示。

再来个onmessage的栗子,详见代码中的的 postMessage/下代码:

其实这个就和webworker一样了,可以理解,serviceWorker可以认为是一种改进后的webWorker。webworker做的是多线程,serviceworker则是用webworker做了个与网络请求相关封装,来监听一些网络事件。当然serviceworker也可以来做很多事情,例如离线缓存应用,甚至替代fiddler作为调试工具。 目前serviceworker的草案还在更新中,部分api仅在FF nightly和chrome canary中使用,相对还需要较大的完善。

(4)注意事项:

处于安全考虑,serviceworker一般用在https上,原因有几点: *防止人为中间层攻击 *推动https使用 *开发工具可以比较自由安全 *https未来会在web中越来越广泛 另外serviceworker一般不能放在cdn上,但是可以通过importscript()来导入cdn上的资源,

(5)扩展:

根据10月草案,serviceworker未来可能会增加后台同步,任务调度和消息推送API。

(6)chrome canary离线小恐龙的游戏

基于serviceworker,chrome canary版本 (chrome37稳定版的好像不行) 在网络不可用时会显示小恐龙冒险的离线游戏,按下空格键,就可以开始呵呵了~~无聊的童鞋可以去试试,如果自己能做个飞机大战就更好了。

三、为什么要使用serviceworker

3.1 未来我们想要做的

未来的web 应用将是离线可用的,而且是能够增量更新的,尤其是在PC客户端的应用

3.2 目前web应用缓存解决方案与不足

目前主要的webapp缓存解决方案主要有以下4种,大家一看都懂,这里只是过一下

3.2.1 基于浏览器头信息的缓存方式 这种方式的缓存过程如下:

说白了,使用浏览器头信息缓存的主要有了两种,一种是判断静态资源http头部的Etag和Last-Modified是否修改,修改则重新请求,否则忽略;当然还有一种根据expires过期时间来判断的,原理一样,但是这两种方法都必不可少的至少会产生大量http请求,即使返回304。而且一旦离线,浏览器就无计可施了。

3.2.2 使用APP Cache

html5提供了App cache来解决静态文件存储的问题,它通过将要缓存的静态文件声明在一个manifest文件清单里,然后在要缓存的html里通过manifest属性关联清单文件即可在下次载入html时优先加载缓存清单中列出的静态文件。相对于浏览器 默认的土鳖方法,静态文件的缓存变得更加可控了。

但是,有些问题依然有些棘手:

  1. 对manifest文件更新,会重新请求所有文件,实际上可能只更新了很少量文件。( 虽然重新请求资源会返回304, 但每个文件还会发起请求,还是发起了网络请求)、针对此点可以只更新需要更新的文件, 比如可以建立一个文件版本或者MD5映射,对相同版本或者MD5不再请求。

  2. manifest文件每次都会请求,我们可以按照一定时间更新一次,或者启动时更新一次,但一旦改变更新就是全量更新

  3. 当然也可以在打开app之前预缓存,提前下载文件或者更新manifest文件。

但这些解决方案,是不是仍然觉得很麻烦,而且依然会有大量的304请求,有木有。

3.2.3 使用localstorage存储

html5支持的,现对于cookie的确丰富了许多,也扩大了容量,方便易用的API也被广泛接受,但是几个问题: 一是无法对静态文件进行存储,二是大小限制,虽然各个浏览器的localstorage最大容量限制也不一样,但是最大的也只是IE9下的7MB,所以要应对离线应用,localstorage仍然是捉襟见肘。

3.2.4 indexedDB缓存

原理说起来比较简单,IndexedDB的做法是,把一些数据存储到浏览器的indexedDB中,当与网络断开时,可以从浏览器中读取数据,用来做一些离线应用,而且不需要你去写特定的sql语句来对数据进行操作,它是nosql的,数据形式使用的是json。这种存储数据的方式似乎无懈可击,容量足够,存取自由,但是对于静态文件就极其麻烦了。

3.3 基于这些,所以我们选择了serviceWorker

它可以是浏览器提供给用户的一个上网代理,通过fetch拦截到用户的所用请求,可以不向服务器发送,并可以将请求转向本地缓存或其它资源文件的加载,无论是数据还是静态文件,然后可以通过javascript的操作进行增量更新应用数据,而且同时不阻塞浏览器的渲染进程。这就很好的解决了我们的问题。虽然目前浏览器支持的程度比较差,但是浏览器的发展速度会很快让我们用到它的。

四、总结

(1) webworker 现在可以在浏览器端做多线程操作,但比较限制

(2) serviceworker是在webworker基础上实现的,它可认为是使用了webworker技术来处理网络请求、响应等方面的事务

(3) 两者目前浏览器兼容性很不好,尤其是serviceworker,草案在更新,特性没有完整,chrome的各分支版本支持都不一样,但仍然还是可以根据这些特性进行一些有趣的开发。

(4)serviceworker可以带给我们很多

参考文档 https://jakearchibald.github.io/isserviceworkerready/ (api支持性现状介绍) http://www.serviceworker.org/# (git主页) http://www.w3.org/TR/2014/WD-service-workers-20140508/#introduction (w3c介绍) http://jakearchibald.com/2014/service-worker-first-draft/ (serviceWorker草案) https://github.com/jakearchibald/isserviceworkerready (样例代码) https://slightlyoff.github.io/ServiceWorker/spec/service_worker/ (10月份更新的草案)

© 著作权归作者所有

共有 人打赏支持
ouven

ouven

粉丝 105
博文 30
码字总数 77829
作品 0
深圳
高级程序员
Android HTML5多线程&本地缓存&文件上传

WebWorker,EventSource,Ajax,WebSocket,WebRTC共同构成网络生态中主要的部分,WebWoker多线程的出现,使得Javascript更容易实现异步编程,特别是在耗时任务使得Javascript更加健壮。 一.支持...

IamOkay ⋅ 2016/03/11 ⋅ 0

解密Angular WebWorker Renderer (二)

很开心再次遇见你,接着上回分解。 先把与通讯相关的类介绍完毕。 与WebWorkerRendererFactory2类对应的就是WebWorkerRenderer2类,该类从类结构中就可以看出包含了各种对DOM节点的操作函数,...

美团点评点餐 ⋅ 2017/08/09 ⋅ 0

解密 Angular WebWorker Renderer (一)

本文主要介绍Angular中的黑科技之WebWorker Renderer,使用Worker线程渲染如何渲染页面?从源码的角度切入,带领带大家看个究竟。 先来做个对比 开发框架版本:Angular 4.x 项目地址:Charw...

美团点评点餐 ⋅ 2017/08/08 ⋅ 0

实现多个标签页之间通信的几种方法(sharedworker)

示例地址 prologue 之前在网上看到一个面试题:如何实现浏览器中多个标签页之间的通信。我目前想到的方法有三种:使用websocket协议、通过localstorage、以及使用html5浏览器的新特性SharedW...

ITgecko ⋅ 04/11 ⋅ 0

webpack offline-plugin 使用

offline-plugin 可以把我们的多页面应用进行缓存,即使这些html文件时独立的。 在webpack打包的webpck.config.js中使用offline-plugin 官方说一般情况下将offline-plugin作为最后一个.需要指...

quanwei9958 ⋅ 2016/10/14 ⋅ 0

Chrome 68 Beta 发布:可将 PWA 应用添加至主屏幕

谷歌宣布 Chrome 68 Beta 已发布,适用于 Android, Chrome OS, Linux, macOS 和 Windows 平台。可在 ChromeStatus.com 上查看 Chrome 68 的完整功能列表。 值得关注的更新 新增将 progressiv...

局长 ⋅ 06/08 ⋅ 3

Javacript 基于Promise的fetch网络请求

一,常见Ajax网络请求 我们常见的网络Ajax请求如下。 二、基于Promise的网络请求 如果使用Promise范式编程,那么我们需要如下编写处理流程 (具体请参考:http://my.oschina.net/ososchina/b...

IamOkay ⋅ 2016/05/27 ⋅ 0

[下载]Chrome 68 Beta 发布:可将 PWA 应用添加至主屏幕

谷歌宣布 Chrome 68 Beta 已发布,适用于 Android, Chrome OS, Linux, macOS 和 Windows 平台。可在 ChromeStatus.com 上查看 Chrome 68 的完整功能列表。值得关注的更新:新增将 progressiv...

开源中国 ⋅ 06/08 ⋅ 0

Parallel.js —— JavaScript 多核编程框架

Parallel.js 是一个多核处理的微型 JavaScript 库。利用越来越成熟的 WebWorker API 实现。

oschina ⋅ 2013/02/14 ⋅ 0

WebWorker初体验

什么是 Web Worker? WebWorker允许开发人员编写能够长时间运行而不被用户所中断的后台程序, 去执行事务或者逻辑,并同时保证页面对用户的及时响应。每个WebWorker执行都称为一个线程,彼此...

Seven_7 ⋅ 2014/07/09 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

个人博客的运营模式能否学习TMALL天猫质量为上?

心情随笔|个人博客的运营模式能否学习TMALL天猫质量为上? 中国的互联网已经发展了很多年了,记得在十年前,个人博客十分流行,大量的人都在写博客,而且质量还不错,很多高质量的文章都是在...

原创小博客 ⋅ 今天 ⋅ 0

JavaScript零基础入门——(十一)JavaScript的DOM操作

JavaScript零基础入门——(十一)JavaScript的DOM操作 大家好,欢迎回到我们的JavaScript零基础入门。最近有些同学问我说,我讲的的比书上的精简不少。其实呢,我主要讲的是我在开发中经常会...

JandenMa ⋅ 今天 ⋅ 0

volatile和synchronized的区别

volatile和synchronized的区别 在讲这个之前需要先了解下JMM(Java memory Model :java内存模型):并发过程中如何处理可见性、原子性、有序性的问题--建立JMM模型 详情请看:https://baike.b...

MarinJ_Shao ⋅ 今天 ⋅ 0

深入分析Kubernetes Critical Pod(一)

Author: xidianwangtao@gmail.com 摘要:大家在部署Kubernetes集群AddOn组件的时候,经常会看到Annotation scheduler.alpha.kubernetes.io/critical-pod"="",以表示这是一个关键服务,那你知...

WaltonWang ⋅ 今天 ⋅ 0

原子性 - synchronized关键词

原子性概念 原子性提供了程序的互斥操作,同一时刻只能有一个线程能对某块代码进行操作。 原子性的实现方式 在jdk中,原子性的实现方式主要分为: synchronized:关键词,它依赖于JVM,保证了同...

dotleo ⋅ 今天 ⋅ 0

【2018.06.22学习笔记】【linux高级知识 14.4-15.3】

14.4 exportfs命令 14.5 NFS客户端问题 15.1 FTP介绍 15.2/15.3 使用vsftpd搭建ftp

lgsxp ⋅ 今天 ⋅ 0

JeeSite 4.0 功能权限管理基础(Shiro)

Shiro是Apache的一个开源框架,是一个权限管理的框架,实现用户认证、用户授权等。 只要有用户参与一般都要有权限管理,权限管理实现对用户访问系统的控制,按照安全规则或者安全策略控制用户...

ThinkGem ⋅ 昨天 ⋅ 0

python f-string 字符串格式化

主要内容 从Python 3.6开始,f-string是格式化字符串的一种很好的新方法。与其他格式化方式相比,它们不仅更易读,更简洁,不易出错,而且速度更快! 在本文的最后,您将了解如何以及为什么今...

阿豪boy ⋅ 昨天 ⋅ 0

Python实现自动登录站点

如果我们想要实现自动登录,那么我们就需要能够驱动浏览器(比如谷歌浏览器)来实现操作,ChromeDriver 刚好能够帮助我们这一点(非谷歌浏览器的驱动有所不同)。 一、确认软件版本 首先我们...

blackfoxya ⋅ 昨天 ⋅ 0

线性回归原理和实现基本认识

一:介绍 定义:线性回归在假设特证满足线性关系,根据给定的训练数据训练一个模型,并用此模型进行预测。为了了解这个定义,我们先举个简单的例子;我们假设一个线性方程 Y=2x+1, x变量为商...

wangxuwei ⋅ 昨天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部