前端开发的workers——web workers、share workers和service workers
文章目录
- 突破单线程的瓶颈WEB WORKERS
- 兼容性
- 私有worker
- “杀死”workers
- 错误调试
- 异步在worker的表现
- 共享的shareWorkers
- service worker
- 使用
- 注册一个service worker
- 使用servers worker
- 设置缓存和缓存数据
- 使用缓存
- 小结
- 参考文献
突破单线程的瓶颈WEB WORKERS
web worker就是一个后台执行JS文件的方法,能够给前端传递信息,前端也可以传递信息给web wokers.
- web workers是一个全新的上下文,与创建它的线程无关。
- 不可以执行dom操作
- 没有window这个对象
- 通过postMessage传递消息
兼容性
if (window.Worker) {// 是否可以使用workers...}
私有worker
index.js
if (window.Worker) {var myWoker = new Worker('./work.js')myWoker.postMessage('send message');myWoker.onmessage = function(e) {console.log('Message received from worker',e.data);}
}
work.js
onmessage = function(e) {console.log('Message received from main script');this.console.log(e.data)console.log('Posting message back to main script');postMessage('I get');
}
输出情况
使用web workers还是比较简单的。
- 对于使用worker的线程而言:
首先就是先注册一个workersnew Worker('path')
然后可以发送数据了
如果需要接受worker返回的数据,就需要注册一个监听事件onmessage
- 对于work.js而言
首先需要写好一个监听数据请求的事件,当然也可以不用监听直接写好执行数据,这里就看需求。
如果设置了监听事件,第一个参数会包含发送过来的数据:如实例中的e.data
当然,worker也可以使用postMessage
主动的发送信息给主线程。
“杀死”workers
不想要workers怎么办?直接停掉它。terminate()
myWorker.terminate();
当然,如果workers不想干活了,也可以“罢工”
直接执行这个函数close();
即可
错误调试
你当然可以 给workers添加错误回调,如监听数据接受的事件一样,只需要在worker设置好监听即可。
onerror = function(e) {e.message// 错误事件e.filename// 错误文件e.lineno // 错误行号
}
异步在worker的表现
onmessage = function(e) {var a=function () {postMessage('I get'+new Date());setTimeout(a, 1000);}setTimeout(a, 1000);
}
我们给主线程也添加异步事件。
var a1 = function () {console.log('主线程'+new Date());setTimeout(a1, 2000);
}
if (window.Worker) {var myWoker = new Worker('./work.js')myWoker.postMessage('send message');myWoker.onmessage = function(e) {console.log('Message received from worker',e.data);}setTimeout(a1, 2000);
}
符合多线程的表现,我们弄的复杂点,让主线程的执行超过1秒,看看是否会阻塞workers。
我们在主线程中添加了一个超过一秒的复杂运算,执行之后的情况如下。
首先说下workers,主线程的阻塞并不会影响workers的异步执行,只是会影响它的输出,因为它是通过发送消息给主线程输出的,所以会等主线程执行完,才会按照顺序执行workers 返回的事件队列。
对于主线程而言,阻塞已经影响到了异步了,因为每一次输出已经超过2秒
。
其实如果workers也有复杂的运算,表现也是和主线程一样的。
这里也可以看出来为什么workers不能操作DOM。
如果workers可以操作DOM的,那么很容易无法更新到最新的状态。
共享的shareWorkers
共享workers,页面之间需要符合同源策略。
index.js
if (!!window.SharedWorker) {var myWorker = new SharedWorker("work.js");myWorker.port.onmessage = function(e) {console.log('Message received from worker');}
}
和workes的区别在于多一个端口调用。
必须设置一个onmessage
或者port.start()
什么时候使用start?
当我们需要addEventListener()
时候
如何使用?
父页面直接执行 myWorker.port.start()
workers执行 port.start()完成打开端口即可
这是为了与后续的work.js的connect
相呼应,因为相当于注册一个端口。
在workers是隐性的,并不是必需进行这步。
如果使用start打开端口,就需要在work.js中调用相同的方法。port.start()
我们来看看work.js的代码
var clients = [];
onconnect = function(e) {var port = e.ports[0];clients.push(port);port.onmessage=function(e) {clients.forEach((item,i)=>{item.postMessage(e.data)})}
}
这里不在是onmessage
来设置监听事件了,我们使用一个变量,将所有的注册端口保存起来,这就是共享的意义,一个worker相当于一个单例,所以页面访问的是同一个上下文。
如果想要广播所有端口,就可以像例子中遍历端口发送数据。
如果你需要对某个特定的页面端口进行特别处理,你可以通过父页面的传递信息约定一个数据,进行判断处理事件。
注意:需要页面是同源的情况下才能访问。
service worker
Service worker是一个注册在指定源和路径下的事件驱动worker。
它采用JavaScript控制关联的页面或者网站,拦截并修改访问和资源请求,细粒度地缓存资源。
常见于网络不可用的情况下
·service worker
同样是workers的另一个类型。但是由于目前支持度不是很高,所以还是遇到很大的兼容性的问题,得不到广泛的使用。
- 同步API(如XHR和localStorage)不能在service worker中使用。
- 出于安全考量,Service workers只能由·
HTTPS
承载
如果一个网页没有了网络,那就将失去所有意义。
所以为了解决这个问题,就需要一个线程脚本,在没有网络连接的时候来控制网页。这样就导致离线页面和service worker的出现。有了这一功能,也代表着网页APP有了与原生APP叫板的底气。
- 缺点:非常明显,开启service worker可能会导致浏览器的缓存数据大大增加。
使用
生命周期:
- 下载
- 安装
- 激活
用户首次访问service works控制的网站和网址的时候,service works会立刻下载。
之后每24小时就会被下载以此,期间可能频繁更新,不过每24小时一定会被下载一次,以避免不良脚本长时间生效。
如果这是首次启用service worker,页面会首先尝试安装,安装成功后它会被激活。
如果新版本的service worker已经下载完但是正在安装,但是不会被激活,这个时候称为 worker in waiting。
直到所有已经加载页面不再使用旧的service worker 的时候,才会激活新的service worker。新激活的service worker称为active worker
注册一个service worker
·'/sw-test/'·
,表示 app 的 origin 下的所有内容。如果你留空的话,默认值也是这个值, 我们在指定只是作为例子。
if ('serviceWorker' in navigator) {// 读取js,进行注册navigator.serviceWorker.register('/sw-test/sw.js', { scope: '/sw-test/' }).then(function(reg) {if(reg.installing) {// 这里有判断service worker状态console.log('Service worker installing');} else if(reg.waiting) {console.log('Service worker installed');} else if(reg.active) {console.log('Service worker active');}}).catch(function(error) {// registration failedconsole.log('Registration failed with ' + error);});
}
使用servers worker
设置缓存和缓存数据
进行了上面的注册,就可以开始使用service worker的API了
// sw.jsself.addEventListener('install', function(event) {event.waitUntil(caches.open('v1').then(function(cache) {return cache.addAll(['/sw-test/','/sw-test/index.html','/sw-test/style.css','/sw-test/app.js','/sw-test/image-list.js','/sw-test/star-wars-logo.jpg','/sw-test/gallery/bountyHunters.jpg','/sw-test/gallery/myLittleVader.jpg','/sw-test/gallery/snowTroopers.jpg']);}));
});
我们先讨论首次加载的情况
这里添加的是安装的监听事件。
waitUntil
是确保service worker安装前,读取到所有的数据。
caches.open()
方法,是创建一个缓存v1
区域,保存下面的文件。这里使用的是promise来实现。
service worker安装完成之后,就开始变成激活状态。
虽然都是缓存,但是service worker不允许使用localstorage
使用缓存
添加fetch
事件,进行操作。
self.addEventListener('fetch', function(event) {event.respondWith(caches.match(event.request).then(function(response) {// caches.match() always resolves// but in case of success response will have valueif (response !== undefined) {return response;} else {return fetch(event.request).then(function (response) {// response may be used only once// we need to save clone to put one copy in cache// and serve second onelet responseClone = response.clone();caches.open('v1').then(function (cache) {cache.put(event.request, responseClone);});return response;}).catch(function () {return caches.match('/sw-test/gallery/myLittleVader.jpg');});}}));
});
当service worker控制的资源被请求时候,就会触发fetch
事件。这些资源包含了指定的scope文档。
事件上的EVENT上的respondWith
劫持HTTPS的请求,劫持之后你就可以进行任何的操作
例子中caches.match
是用于匹配本地资源是否存在这个文件。
然后判断本地缓存是否有网络请求的响应报文,如果有则使用本地资源缓存,如果没有则使用fetch
进行请求,当然也可以使用xht
,如果使用后者,你还需要配置路径和方法,而fetch是封装好的API,只需要传入请求文段即可发送请求。
fetch
这个方法本身是支持promise
的,所以是异步进行请求的。
如果想要下次不需要网络请求,你可以将请求报文段保存到缓存,这样下次请求能够直接使用本地的缓存文件了。
最后如果不出意外,请求会返回一些数据,你可以将他们保存到本地,然后再返回给客户端。
cache.put(event.request, responseClone);
小结
其实service worker更新一个中间代理服务器。它特别的地方是离线状态也可以访问,如果存在你需要的资源就可以返回给你,这样达到离线访问web app的目的。
当然,这种API自然对资源管理要求更加严格,如果滥用很可能会导致缓存过大,打开一个网页会让计算机占的内存变大等问题。目前支持度主要是谷歌的CHROM 和火狐的FIRFOX。这些都是默认关闭的,需要用户自己打开才能使用这个API,所以目前还处在测试的环节。
不过抛开这些短板来看,web app或许真的可能会代替native app。
- 应用场景
- 响应推送:启动一个service work,获取服务器推送的消息,不会影响用户体验
- 后台同步:启动一个service work,更新服务器的数据,不会影响用户体验
- 自定义模板用于特定URL模式:因为service worker能够劫持HTTP请求,所以可以自己自定义格式进行处理。
- 性能增强:我们可以对用户的预处理进行预请求,比如图片的懒加载,可以先使用service worker保存前几页的数据,这样用户交互的时候,就会减少等待时间。
其实上面的功能,普通的web workers都可以实现,但是由于service work已经封装好了API,如劫持HTTP请求的方法,对上面的场景实现起来非常方便。
参考文献
MDN WEB WORKERS
前端开发的workers——web workers、share workers和service workers相关推荐
- php前端开发培训,杭州web前端培训技术学校(web前端开发和php开发)
杭州web前端培训技术学校,选择的时候请记住杭州web前端培训中的web前端框架,web前端开发和ui设计,web前端开发和php开发,web前端开发好不好,学历低能否学习web前端,web适用那些人 ...
- 2021年web前端开发视频教程,自学web前端开发技术,全套web前端学习路线笔记
2021年web前端开发视频教程,自学web前端开发技术,全套web前端学习路线笔记 [导读]:初学web前端的小伙伴经常会遇到的问题,1.没方法 2.没资源 3.没经验,不知道从何开始 ,代码哥(D ...
- html前端开发是什么,web前端开发需要会什么
对于很多刚入坑it行业的新人小白来说,web前端开发算是一个对技术要求比较高的岗位,我们经常在一些企业招聘上可以看到web前端的工程师需要掌握多个技能,甚至后端的开发语言都需要掌握一两门,这着实吓坏了 ...
- 0基础学习前端开发,高职web前端开发技能大赛
零基础学web前端开发要怎么去学? 首先要学习的就是基础知识:html.css和JavaScript.HTML是内容,CSS是表现,JavaScript是行为.前端开发的门槛其实非常低,与服务器端语言 ...
- Hapi.js 起步 - 写给前端开发的 Node Web 框架入门
为什么选择 Hapi 或许你已经使用过 Express, Koa2 等 Node.js 的 WEB 框架,在构建 WEB 应用程序时,你的工作仅仅是产出 RESTFUL API,或者通过 Node 调 ...
- 前端开发和html5,Web前端和HTML5前端相同吗 有区别吗
学习web前端和学习HTML5是否一样呢,当前的社会技术更新太快了,小伙伴们都不知道要学习什么专业了.最近有学员咨询说,什么是web前端,什么是HTML5前端,两者之间有什么区别呢? 今天IT培训网小 ...
- html5前端开发做什么,Web前端能做什么开发
对于想要学习HTML5大前端的人来说,从哪里开始入手是困扰他们的难题.前端开发工作已经变的越来越复杂,仅仅是想罗列一份前端开发的学习列表就已经是一件艰巨的工作.曾经只要会编写HTML, CSS和Jav ...
- Web前端开发敲门砖 ——《Web前端工程师修炼之道》
随着多设备.浏览器和Web标准的演变革命,前端正在成为兼顾逻辑.性能.交互.体验的综合性岗位. 前端开发入门又相对容易,必须掌握的HTML+CSS+JS非常容易学习,如果你能再了解一定后端知识,对业务 ...
- html前端开发学年论文,web前端毕业设计论文.doc
web前端毕业设计论文 毕 业 论 文 题目:响应式企业网站设计与实现学生姓名:罗智刚学号:1202012132专业班级:B12计算机科学与技术2班指导教师:李莉企业导师:林志宏二级学院:电气与信息工 ...
- 前端开发人员必备Web前端面试题与答案 西安尚学堂
HTML: 1.对WEB标准以及W3C的理解与认识 标签闭合.标签小写.不乱嵌套.提高搜索机器人搜索几率.使用外 链css和js脚本.结构行为表现的分离.文件下载与页面速度更快.内容能被更多的用户所访 ...
最新文章
- Linux/windows系统定时任务调度总结
- python opencv手册_教你用Python实现5毛钱特效(给你的视频来点料)
- RCC 2017 Qual 1 Mail.Ru, April 2, 2017 Problem B. Painting the Wall
- (王道408考研操作系统)第二章进程管理-第三节4:信号量机制(整型、记录型信号量和P、V操作)
- php web 简单的系统,Slim 简单而强大的 PHP 微型 Web 开发框架 - 资源分享
- Zookeeper基础使用
- openstack mitaka 完整安装详细文档(亲测,花了3天时间)
- java实现活动安排问题_贪心算法-活动安排问题
- HFSS - 圆形双馈微带天线
- 并发测试工具Jmeter安装与简单使用
- Chrome 扩展程序 CrxMouse Techzero优化版 更新至 v3.0.4
- 统计遗传学:第五章,多基因评分PGS
- Win10查看电脑的开机时间和关机时间记录
- 全文翻译 | 华为、北大、悉尼大学:最新视觉Transformer综述(2017-2020年)
- 高德地图WEB端,在所画的圆(Circle)内显示在圆(Marker)内的点
- C语言实现贪吃蛇小游戏(详解)
- pandas中的滚动窗口rolling函数和扩展窗口expanding函数
- 钙钛矿Cs2AgBiBr6|三氟乙胺碘F3EAI|4-三氟甲基苯胺溴CF3PhABr
- Java 三大器之监听器Listener
- 时间戳转换为日期格式 C/C++ 学习日记 新手讲解