全国免费咨询:

13245491521

VR图标白色 VR图标黑色
X

中高端软件定制开发服务商

与我们取得联系

13245491521     13245491521

2025-02-13_不会webworker,你做什么性能优化??

您的位置:首页 >> 新闻 >> 行业资讯

不会webworker,你做什么性能优化?? 点击关注公众号,“技术干货”及时达! 前言本来这篇文章是打算写我之前「那个迭代」的「首屏优化」的,但是我做的那些优化,前几天上了生产,效果「并不如意」,因为生产环境不能随便动,我只能在灰度环境上测试,但是灰度测试后确实是比之前好的。那篇文章我也写了大半了,过几天发出来大家指点一下。然后我最近看了评论想着使用webworker去优化一下我那坨列表,然后我之前也没用过,最近也研究了一下,所以这篇文章就给大家分享一下webworker怎么用。其实挺简单的,但是遇到了一些坑!希望大家使用的时候能注意一下。 什么是web worker??mdn的链接 https://developer.mozilla.org/zh-CN/docs/Web/API/Worker/Worker ?webworker是html5的一个api,它的作用就是新开一个线程去做一些操作,因为这个线程并不会阻塞主线程,所以可以去提高网页的性能。其实可以把他「当成一个函数」,传参进行计算得到你想要经过一些代码处理的东西。 Demo这里就以计算「计算斐波那契数列」为例子去给大家演示。 「主线程脚本(index.html)」 在主线程中 「new」一个worker对象,传参的是一个js脚本路径,「不能传其他类型的文本」,也必须是「同源」的。然后通过message事件和postmessage进行通信即可。 !DOCTYPEhtml htmllang="en" head metacharset="UTF-8" titledemo/title /head body buttononclick="startCalculation()"斐波那契数列/button pid="result"/p script functionstartCalculation(){ //创建一个WebWorker对象,指定worker.js作为工作线程的脚本 constworker=newWorker('worker.js'); worker.postMessage(20) //监听工作线程发送的消息 worker.onmessage=function(event){ document.getElementById('result').innerHTML='斐波那契数列的第20项是:'+event.data; //通知关闭线程 worker.postMessage('close') } /script /body /html 「工作线程(work.js)」 这里主要的点是「self」,在工作线程中的self就相当于「主线程的window」,也就是window中很多东西在self中也能使用。但是工作线程是没有去「获取dom的权限」的,所以他不能也不建议去操作dom。然后就是通过message和postMessage去通信。 //计算斐波那契数列的函数 functionfeibo(n){ if(n===0||n===1){ return } returnfeibo(n-1)+feibo(n-2); } //计算斐波那契数列的第10项并发送结果给主线程 self.onmessage=function(e){ console.log(e.data); if(e.data=='close'){ //关闭线程 self.close() return } constdata=feibo(e.data); self.postMessage(data); }; 方法属性selfself是对工作线程自身全局对象的引用。类似于浏览器主线程中的window对象,要注意的self不能访问 DOM 相关内容 postmessge和message当主线程使用worker.postMessage发送消息时,工作线程中的message事件处理函数就会被触发。当工作线程使用worker.postMessage发送消息时,主线程中的message事件处理函数就会被触发。所以就是用来通信的 importScripts用于在工作线程中加载外部脚本。可以同时加载多个脚本,并且脚本会按照它们在importScripts函数参数中的顺序「依次加载」,不过我感觉这个方法应该很少用。 terminate(在「主」线程中使用)worker.terminate(); close (在「工作」线程中使用)self.colse(); 是吧。其实webworker就这么点东西,就是相当一个「装机师傅」,你把主板,cpu,显卡,内存,风扇...给他,师傅就可以还给你一台主机。然后我在用的时候就发现会有一些「坑」,就会导致出现bug。 坑1:postMessage不知道大家知不知道,postMessage是一种「异步通信」。什么叫异步通信呢。就是我给你通知了,但是我不会去等你执行代码,我继续执行我的代码。大家可以用上面的demo试一下。我一开始以为是和我们vue的组件自定义事件通信那样,是「同步通信」的。其实应该很多人都不知道这个是同步通信的,这个很重要的,工作中不注意这个时机,就会导致bug,我记得我在面试的时候也被问到过。我下面写了个vue3的自定义通信的小demo,然后在自定义事件中写了for循环阻塞5秒钟,大家可以复制跑一下看看。 parent.vue template Child@chageFn="chageFn"/Child /template scriptsetup importChildfrom"./child.vue"; constchageFn=()={ conststart=Date.now(); constwaitTime=5000;//5秒,单位是毫秒 for(leti=0;Date.now()-startwaitTime;i++){ } console.log("5秒时间已过,继续执行后续代码"); }; /script stylelang="scss"scoped/style child.vue template button@click="clickFn"点击我/button /template scriptsetup import{defineEmits}from"vue"; constemit=defineEmits(["chageFn"]); constclickFn=()={ emit("chageFn"); console.log("1"); }; /script stylelang="scss"scoped/style 当我们点击的时候就可以发现,是「在五秒后打印1」,并不会立即打印1,但如果是postMessage通信是会立即打印1的。然后这个同步通信并不是说一定会等自定义函数执行完才会走后面的代码,如果这个自定义函数中是异步代码,是会先打印1的,就是正常的「事件循环」机制,大家也可以试试。 坑2:序列化和反序列化postMessage在进行通信时会对数据进行「序列化」的,在message事件接收数据是会「反序列」的,啥意思呢,就是类似于JSON.parse和JSON.stringify,这两个api就是将js的数据类型转化成JSON格式的数据,但是postMessage并不是转化成JSON格式,它是一种「结构化克隆算法」,具体我也不清楚。他们的共同点都是不能转化函数,JSON.stringify是会将函数变成undefind,postMessage是报错。 !DOCTYPEhtml htmllang="en" head metacharset="UTF-8" metaname="viewport"content="width=device-width,initial-scale=1.0" titleWebWorkerFunctionandCircularReferenceExample/title /head body script constfn=()={ console.log(1) } console.log(JSON.stringify(fn))//undefind constworker=newWorker('worker.js') worker.postMessage(fn)//报错 /script /body /html 坑3:如何正确的去通信以及正确的去关闭工作线程当我们使用webworker的时候不可能说每使用一次就new一次webwoker,而是每次都是使用这一个线程进行处理。然后可能会导致什么问题呢?还是那个装机师傅的例子,「有两个人同时去找这个师傅装机,装完了师傅不知道这两个机子分别是谁的」。那师傅肯定没有这么笨,他肯定会贴个标签说这个是他的,那个是她的。所以,当我们通信的时候就需要去规定通信的格式。比如下面这样,当主线程给工作线程通信的时候,传一个id字段实现唯一性,当工作线程回复的时候也带上这个字段,大家具体情况具体分析。 constparams={ id:"1", params:{ } } constresponse={ id:"1", data:{ } } 关闭工作线程是有两种方式的,一种是「主线程去关闭」,另一种是「工作线程自己关闭」。如果协调不好的话就可能会导致工作线程的代码并没有执行完成就关闭了,然后就会引出很多问题。不过这个我倒是没遇到过hhh,其实我觉得可以去统一一下关闭的地方。比如,「统一由主线程去关闭」,当工作线程想关闭的时候,去通过postmessage去通知主线程去关闭。 总结我觉得webworker其实大部分前端应该是很少用到的,反正我是第一次用。不过也并不是很难,稍微看一下就能学会,就能使用在工作上了。这应该也只会在「性能优化」的时候去使用,毕竟在大多数情况下封装函数就行了,谁会想着新开一个线程去处理,麻烦死了。只能说,技多不压身,学不死就往死里学! 点击关注公众号,“技术干货”及时达! 阅读原文

上一篇:2019-10-28_日清找Nendo出了一款歪脖子叉,居然还限量 下一篇:2021-03-09_极限运动幕后揭秘,摄影师才是大神

TAG标签:

17
网站开发网络凭借多年的网站建设经验,坚持以“帮助中小企业实现网络营销化”为宗旨,累计为4000多家客户提供品质建站服务,得到了客户的一致好评。如果您有网站建设网站改版域名注册主机空间手机网站建设网站备案等方面的需求...
请立即点击咨询我们或拨打咨询热线:13245491521 13245491521 ,我们会详细为你一一解答你心中的疑难。
项目经理在线

相关阅读 更多>>

猜您喜欢更多>>

我们已经准备好了,你呢?
2022我们与您携手共赢,为您的企业营销保驾护航!

不达标就退款

高性价比建站

免费网站代备案

1对1原创设计服务

7×24小时售后支持

 

全国免费咨询:

13245491521

业务咨询:13245491521 / 13245491521

节假值班:13245491521()

联系地址:

Copyright © 2019-2025      ICP备案:沪ICP备19027192号-6 法律顾问:律师XXX支持

在线
客服

技术在线服务时间:9:00-20:00

在网站开发,您对接的直接是技术员,而非客服传话!

电话
咨询

13245491521
7*24小时客服热线

13245491521
项目经理手机

微信
咨询

加微信获取报价