详解 WebWorker 的概念、使用场景、示例

前言

提到 WebWorker,可能有些小伙伴比较陌生,不知道是做什么的,甚至不知道使用场景,今天这篇文章就带大家一起简单了解一下什么是 webworker!

概念

WebWorker 实际上是运行在浏览器后台的一个单独的线程,因此可以执行一些耗时的操作而不会阻塞主线程。WebWorker 通过与主线程之间传递消息实现通信,这种通信是双向的。WebWorker不能直接访问 DOM,也不能使用像 window 对象这样的浏览器接口对象,但可以使用一些WebWorker 标准接口和 Navigator 对象的部分属性和方法。

为什么使用WebWorker?

  1. 提高应用响应能力:主线程被独占执行一些耗时的计算或操作时,会导致UI无响应。WebWorker 可以把这些任务转移到后台线程,从而保证主线程的运行,提高应用的响应能力。
  2. 充分利用多核CPU:现代CPU都是多核的,WebWorker 可以让 Web 应用利用多核 CPU 的并行计算能力,充分发挥计算机硬件性能。
  3. 避免渲染阻塞:JavaScript 运行在主线程,如果主线程一直占用,就无法执行 GUI 渲染任务,导致界面渲染受阻。WebWorker 把一些费时任务分流到后台线程就可以避免这一问题。
  4. 后台持续运行:WebWorker 所在后台线程可持续运行,即使页面被挂起或最小化,任务仍在后台执行,非常适合一些需要长时间运行的操作。

使用场景

一般来说,当遇到如下几种情况时可以考虑使用 WebWorker:

  1. 大量数据的计算/处理:比如图像处理、数据分析等
  2. 长时间运行的操作:如一些复杂的数学计算
  3. 非阻塞式操作:希望执行一些耗时操作时不阻塞主线程

示例

假设我们有一个需要计算斐波那契数列的任务,我们可以使用 Web Worker 来进行计算,以避免阻塞主线程。以下是一个简单的示例:

主线程

主线程创建 worker 实例,向子线程通过 postMessage 发送消息,通过 onmessage 监听子线程返回的数据。

  const myWorker = new Worker('./worker.js')myWorker.onmessage = function (e) {console.log('Fibonacci result:', e.data)}myWorker.postMessage(40) // 请求计算斐波那契数列的第40项

worker.js

在同级目录下创建 worker.js文件,通过 onmessage 接收主线程发来的数据,计算后通过postMessage 将计算结果返回主线程。

self.onmessage = function (e) {const n = e.datalet a = 0,b = 1,tempfor (let i = 2; i <= n; i++) {temp = aa = bb = temp + b}self.postMessage(b)
}

运行结果

可以看到主线程打印出 webworker 计算的运行结果

Vue、React项目使用

接下来为大家演示 vue 以及 react 项目如何使用

Vue使用

vue版本:"vue": "^2.6.14",vue-cli版本:@vue/cli 5.0.8安装 worker-loader

页面使用

<template><div>我的页面</div></template>
<script>
export default {name: 'MyselfView',data() {return {worker: null,}},mounted() {// 创建 WebWorker 实例this.worker = new Worker(new URL('./worker.js', import.meta.url))console.log('worker: ', this.worker)this.worker.postMessage(40) // 请求计算斐波那契数列的第40项this.worker.addEventListener('message', (event) => {console.log('Fibonacci result:', event.data)})},beforeDestroy() {// 组件销毁时终止 WebWorkerthis.worker.terminate()},
}
</script>

worker.js

// worker.js
self.addEventListener('message', (e) => {console.log('e: ', e)const n = e.datalet a = 0,b = 1,tempfor (let i = 2; i <= n; i++) {temp = aa = bb = temp + b}self.postMessage(b)
})

效果 

React使用 

react版本: "react": "^18.2.0"

import React, { useEffect } from 'react'
// import WorkerScript from './worker.worker.js'const Demo = () => {useEffect(() => {const worker = new Worker(new URL('./worker.worker.js', import.meta.url))worker.onmessage = function (e) {console.log('Fibonacci result:', e.data)}worker.postMessage(40) // 请求计算斐波那契数列的第40项// 使用 worker ...return () => worker.terminate()}, [])return (<div><p>count的值</p></div>)

效果

 

注意

由于我们在项目开发时,使用不同的打包工具(vite/webpack)。幸运的是,最新版的vite/webpack都支持Web Worker了。

我们可以通过:new URL()的方式 --vite/webpack都支持

new Worker(new URL('./worker.js', import.meta.url)
);

总结

WebWorker是一种在 Web 应用中实现多线程运行的技术,可以将耗费 CPU 的任务交给后台线程处理,避免阻塞主线程,从而提高Web应用的响应性能和用户体验。 总之,WebWorker的引入解决了Web应用长期以来在单个线程中运行所带来的诸多问题,有效提升了Web应用的运行性能和用户体验。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/571713.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

eNSP ppp验证实验

1、R1和R2使用PPP链路直连&#xff0c;R2和R3把2条PPP链路捆绑为PPP MP直连 2、按照图示配置IP地址 3、R2对R1的PPP进行单向chap验证 4、R2和R3的PPP进行双向chap验证 实验步骤&#xff1a; R1配置&#xff1a; #修改名称 <Huawei>sys Enter system view, return u…

javascript基础代码练习之超速罚款

<!DOCTYPE html> <html> <head><meta charset"UTF-8" /><title>Nauji</title> </head> <body><script>function punish(speed) {const limit 120;if (speed < limit) {return 未超速;} else if (speed &l…

【二叉树】Leetcode 104. 二叉树的最大深度【简单】

二叉树的最大深度 给定一个二叉树 root &#xff0c;返回其最大深度。 二叉树的 最大深度 是指从根节点到最远叶子节点的最长路径上的节点数。 示例1 输入&#xff1a;root [3,9,20,null,null,15,7] 输出&#xff1a;3 解题思路 二叉树的最大深度可以通过递归方式来求解…

canvas跟随鼠标画有透明度的椭圆边框

提示&#xff1a;canvas跟随鼠标画有透明度的椭圆边框 文章目录 前言一、跟随鼠标画有透明度的椭圆边框总结 前言 一、跟随鼠标画有透明度的椭圆边框 test.html <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8">&…

矩阵间关系的建立

参考文献 2-D Compressive Sensing-Based Visually Secure Multilevel Image Encryption Scheme 加密整体流程如下: 我们关注左上角这一部分: 如何在两个图像之间构建关系,当然是借助第3个矩阵。 A. Establish Relationships Between Different Images 简单说明如下: …

docker拉取镜像

docker 拉取镜像 命令格式 docker pull 仓库名称[:标签] 从下载过程可以看出&#xff1a; &#xff08;1&#xff09;镜像文件是由若干层组成&#xff0c;即&#xff1a;AUFS联合文件系统。这是实现增量保存与更新的基础 &#xff08;2&#xff09;下载过程会输出各层镜像的信…

MySQL数据库备份策略与实践详解

目录 引言 一、MySQL数据库备份的重要性 &#xff08;一&#xff09;数据丢失的原因 &#xff08;二&#xff09;数据丢失的后果 二、MySQL备份类型 &#xff08;一&#xff09;根据数据库状态 &#xff08;二&#xff09;根据数据的完整性 &#xff08;三&#xff09;…

Python7:接口自动化学习1 RPC

API&#xff08;Application Programmming Interface&#xff09; 应用编程接口&#xff0c;简称“接口” 接口&#xff1a;程序之间约定的通信方法 特点&#xff1a;约定了调用方法&#xff0c;以及预期的行为&#xff0c;但是不透露具体细节 意义&#xff1a;程序能解耦&…

HttpRunner 接口自动化测试框架实战,打造高效测试流程

简介 2018年python开发者大会上&#xff0c;了解到HttpRuuner开源自动化测试框架&#xff0c;采用YAML/JSON格式管理用例&#xff0c;能录制和转换生成用例功能&#xff0c;充分做到用例与测试代码分离&#xff0c;相比excel维护测试场景数据更加简洁。在此&#xff0c;利用业…

【数学】第十三届蓝桥杯省赛C++ A组/研究生组 Python A组/研究生组《数的拆分》(C++)

【题目描述】 给定 T 个正整数 &#xff0c;分别问每个 能否表示为 的形式&#xff0c;其中 , 为正整数&#xff0c;, 为大于等于 2 的正整数。 【输入格式】 输入第一行包含一个整数 T 表示询问次数。 接下来 T 行&#xff0c;每行包含一个正整数 。 【输出格式】 对于…

TF卡系统备份与还原

本文介绍一种用备份还原方法&#xff0c;快速实现TF启动卡制作&#xff0c;使用方便&#xff0c;无需安装linux系统&#xff0c;需要使用Diskgnius软件。 安装Diskgnius&#xff0c;64位绿色版本&#xff0c;无需安装&#xff0c;直接运行即可。运行Diskgnius软件&#xff0c;将…

二叉树|235.二叉搜索树的最近公共祖先

力扣题目链接 class Solution { private:TreeNode* traversal(TreeNode* cur, TreeNode* p, TreeNode* q) {if (cur NULL) return cur;// 中if (cur->val > p->val && cur->val > q->val) { // 左TreeNode* left traversal(cur->left, p, q)…