全国免费咨询:

13245491521

VR图标白色 VR图标黑色
X

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

与我们取得联系

13245491521     13245491521

2024-05-28_运营:别再让你的页面一直loading 了

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

运营:别再让你的页面一直loading 了 点击关注公众号,“技术干货”及时达! 运营:别再让你的页面一直loading 了May-17-2024 15-36-38.gif第一轮 battle Q:我想下载一个大文件,界面一直转圈,很耽误时间,我想在下载的时候还做点其他事情 A:一直转圈就一直等呗,反正还能摸会(奈何小姐姐太想做牛马了) 第二轮 battle Q:不行,为什么别人的浏览器,下载软件/文件 就能操作界面,你这就一直转圈,什么都做不了 A:我们js 是单线程,一个时间只能做一件事,你不能在下载文件的时候,还操作界面吧...逐渐语无伦次,行,我给你试着优化优化.. image.png最终效果 save.gif无敌.gif可以看到,下载文件 页面不再转圈,并且可以在界面操作,但是在点击操作1,2,到3的时候,会卡顿一下,下面会说为什么会卡这一下 开始分析执行文件下载操作,把转圈逻辑去掉不就行了,but:是不转圈了,下载的时候,依然操作不了界面 js 是一个单线程,一个时间只能做一件事,密集的cpu 计算,导致网站反应迟钝,就像卡了一样resolve:把下载文件这个耗时操作,放在其他线程操作,等到操作完毕,再通知主线程,执行完了。就像发布订阅模式一样,主线程不用执行密集的计算,也不用特意等密集计算的结果,执行完,告诉我就行了 技术使用 Web Workers摘自 MDN https://developer.mozilla.org/zh-CN/docs/Web/API/Web_Workers_API/Using_web_workers#web_workers_api Web Worker 为 Web 内容在后台线程中运行脚本提供了一种简单的方法。线程可以执行任务而不干扰用户界面。此外,它们可以使用XMLHttpRequest(尽管responseXML和channel属性总是为空)或fetch(没有这些限制)执行 I/O。一旦创建,一个 worker 可以将消息发送到创建它的 JavaScript 代码,通过将消息发布到该代码指定的事件处理器(反之亦然)。 为什么要用它:worker 的一个优势在于能够执行处理器密集型的运算 而 「不会阻塞 UI 线程」 「不会阻塞 UI 线程」 「不会阻塞 UI 线程」 「不会阻塞 UI 线程」 重要的事情说三遍 ???????????????????????????????????????????? 基本使用主线程生成一个专用 workerconst myWorker = new Worker("worker.js"); // worker.js 是一个脚本的 URI 来执行 worker 线程 专用 worker 中消息的接收和发送就俩主要方法 postMessage onmessage 引入脚本与库Worker 线程能够访问一个全局函数importScripts()来引入脚本,该函数接受 0 个或者多个 URI 作为参数来引入资源;以下例子都是合法的: importScripts();/*什么都不引入*/ importScripts("foo.js");/*只引入"foo.js"*/ importScripts("foo.js","bar.js");/*引入两个脚本*/ importScripts("//example.com/hello.js");/*你可以从其他来源导入脚本*/ ESModule 模式constworker=newWorker('worker.js', {type:'module'//指定worker.js的类型} 文件下载代码baseCodeimport{writeFile,utils}from'xlsx' /**模拟生成大文件数据*/ constgenerateLargeFileData=()={ constdata=[] for(leti=0;i10000;i++){ data.push({ id:i+1, name:`User${i+1}`, email:`user${i+1}@example.com`, age:Math.floor(Math.random()*100)+1 }) } returndata } 一只转圈的代码/**下载大文件*/ constdownloadExcel=async()={ //模拟生成大文件数据 constdata=generateLargeFileData() loading.value=true //模拟一段短暂的等待时间,确保状态更新 awaitdelay(1000) //卡死的罪魁祸者 //将数据转换为Excel格式 constws=utils.json_to_sheet(data) constwb=utils.book_new() utils.book_append_sheet(wb,ws,'Sheet1') writeFile(wb,'test.xlsx') loading.value=false } 使用webworker,将耗时计算放到 webworker 线程,解决阻塞ui的问题主线程 constmyWorker=newWorker('downloadWorker.js') myWorker.onmessage=(event)={ letwb=event.data //这里也会占用主线程的ui渲染,所以会卡一下 writeFile(wb,'test.xlsx') ElMessage.success('下载任务已在后台运行,可以继续操作界面其他任务') } /**下载大文件*/ constdownloadExcel=async()={ constdata=generateLargeFileData() myWorker.postMessage(data) } worker 线程 image.png//非模块化文件,public打包本身就是线上文件了 importScripts("./xlsx.js");//线上地址,或者本地地址 self.onmessage=(e)={ //将数据转换为Excel格式 constws=XLSX.utils.json_to_sheet(e.data) constwb=XLSX.utils.book_new() XLSX.utils.book_append_sheet(wb,ws,'Sheet1') //writeFile(wb,'test.xlsx')//这里会操作dom,所以将操作dom放到主线程做 self.postMessage(wb) self.close() } 细节补充本文主要介绍了专用worker,其实还有 共享 worker【主要做多页面标签通信】, ServiceWorkers 【主要做网络拦截,可以看一下之前写的pwa文章【https://juejin.cn/post/7062681470116036616】,离线缓存就是使用ServiceWorkers】 在主线程中使用时,onmessage和postMessage()必须挂在worker对象上,而在 worker 中使用时不用这样做。原因是,在 worker 内部,worker 是有效的全局作用域(就像window.xxx ,window 一般可以不写) worker的关闭 //main.js(主线程) constmyWorker=newWorker('/worker.js');//创建worker myWorker.terminate();//关闭worker //worker.js(worker线程) self.close();//直接执行close方法就ok了 worker 错误监听 messageerror 关于主线程里的 new Worker('downloadWorker.js') 这个脚本,必须是本地/或者网络地址,这里写的是项目运行地址 匹配相应的worker。这里大家也会发现一个问题,就是这个worker是全局性的,放在public 是一个不错的选择,再者打包后,public 下本身也是会放在服务器上 用完worker, 要及时关闭,他是不会自己结束的。选择 在worker 关闭,或者主线程关闭,会有区别 其实小文件下载,用worker 有点画蛇添足,本身使用worker 也是一种消耗 详细的参考资料以及代码地址MDNhttps://developer.mozilla.org/zh-CN/docs/Web/API/Web_Workers_API/Using_web_workershttps://developer.mozilla.org/zh-CN/docs/Web/API/SharedWorkerhttps://developer.mozilla.org/zh-CN/docs/Web/API/Service_Worker_APIMDN code仓库https://github.com/mdn/dom-examples可以下载下来直接调试,最好是起一个本地服务: http-server image.png掘金https://juejin.cn/post/7139718200177983524https://juejin.cn/post/7345672631323115570#heading-15代码地址https://gitee.com/Big_Cat-AK-47/vue-project.git ??????番外 ????????????最近在做一个项目,主要技术栈是v3 + el-plus + axios + pinia + vite5 + UnoCSS, 就是上面的仓库地址,主要是总结平时做的亮点/难点。有志同道合的朋友,想一起code,欢迎滴滴我 目前打算做的模块 首页大屏数据可视化递归菜单/路由权限项目基建搭建大文件上传/断点续传/秒传/进度控制 以及一些优化手撸实现一个虚拟列表多语言/多主题 脚本编写《目前是在项目里,后期打算发布一个npm,包括封装常用方法,也会同步到npm》在线聊天项目工程化优化点击关注公众号,“技术干货”及时达! 阅读原文

上一篇:2025-04-29_京东公关舆论战,情绪价值拉满了| 4月营销案例top5 下一篇:2023-03-02_实在不行,就去种地

TAG标签:

15
网站开发网络凭借多年的网站建设经验,坚持以“帮助中小企业实现网络营销化”为宗旨,累计为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
项目经理手机

微信
咨询

加微信获取报价