Web Worker:JS多线程的伪解药?

2023-11-09 21:54
文章标签 多线程 web js worker 解药

本文主要是介绍Web Worker:JS多线程的伪解药?,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

前言

在前端开发领域,JavaScript 的单线程限制一直是一个难以忽视的挑战。当谈到解决JavaScript的单线程限制时,HTML5引入的Web Worker被普遍认为是一剂解药💊。同时,业界中大量的文章也是聚焦于讨论web worker的神奇力量。然而,本文将另辟蹊径,和您一同探索Web Worker神秘的另一面。

js单线程限制及多线程能力的需求

js的一大特点就是单线程。对于单线程,一句最经典的概述就是“同一时间只能执行一个任务”。

在JavaScript设计之初,其单线程模型是由其主要用途和初衷所决定的。JavaScript作为一门浏览器端的脚本语言,最初的主要任务是处理用户交互。设想一下,如果JavaScript被设计为多线程,那么在用户交互中进行多线程同步操作DOM,为了保证准确性必然会引发竞态分配等复杂问题。另外,对于客户端来说也可能引发性能和资源消耗等多种复杂问题,这时的多线程在这个背景下反而显得过于臃肿。

随着Web技术的不断演进,JavaScript的单线程模型已经无法满足日益复杂的业务需求和以及带来的性能要求。为了解决这些问题,JavaScript引入了一些如ajaxsetTimeoutrequestAnimationFrame等机制,但需要明确的是,这些机制不过是通过EventLoop来制造的多线程假象,其并没有改变JavaScript单线程的本质。

至今,现代Web应用中用户交互变得越来越复杂,以及数据处理需求的增加,JavaScript应用需要更强的计算能力和更快的响应性,单线程模型面临着着挑战愈发严重。这就引出了一个关键问题:如何在保持JavaScript的单线程特性的同时,充分利用多核处理器来提高性能以满足用户的需求?在这样的背景下,Web Worker技术应运而生。

web worker的定义

或许在您的项目中尚未使用过Web Worker,但实际上它已经存在了很长时间。早在2009年,W3C便提出了 Web Worker 草案,2011年正式称为HTML5标准的一部分。

Image Description

W3C对Web Worker的定义如下:

an API for running scripts in the background independently of any user interface scripts.

兼容性

image.png

一个最最最最最简易明了的示例🌰
 
// 主线程代码
const worker = new Worker('worker.js');
worker.postMessage('Hello from the main thread!');
worker.onmessage = (event) => {console.log('Message from Web Worker:', event.data);
};// worker.js
self.onmessage = (event) => {console.log('Message from main thread:', event.data);self.postMessage('Hello from the Web Worker!');
};

其他类型扩展

除了专用worker类型(Dedicated Web Worker),还有两种特殊的 Web Worker:SharedWorer和ServiceWorker。

  • SharedWorker可以在多个浏览器Tab中访问到同一个Worker实例, 可实现多Tab共享数据, 如共享webSocket连接等。然而看起来很美好, 但兼容性问题一度严重。特别是safari从12年ios5开始支持,到在ios7~15中一度不支持,再到ios16又支持,真是一波三折纠结死了!
  • ServiceWorker可以拦截和处理网络请求,实现离线缓存、推送通知和其他高级网络功能,也非常有意思。做过PWA的同学知道SW是其核心一环。

sharedWorker兼容性:

image.png

Web Worker 的优势🚀

Web Worker与主线程相互独立,可以在不影响主线程性能的情况下执行一些耗时操作而不会阻塞主线程,特别是在处理复杂任务和长时间运行的操作时非常有用。它的主要优势如下:

  • 独立运行:Web Worker在一个独立的线程中运行,与主线程互不干扰。这可以避免主线程因执行耗时操作而卡顿,从而提高页面的响应速度和用户体验。
  • 隔离机制:Web Worker无法直接访问或操作DOM元素。这种隔离机制可以防止潜在的页面修改和恶意攻击,确保网页的安全性和稳定性。
  • 多线程异步执行: Web Worker允许您在标签页进程中创建多个独立线程,每个线程都可以在不同的内核上执行,因此可以实现并行计算。

Web Worker的实际应用场景

在实际项目中,Web Worker更适合处理以下场景:

  • 计算密集型任务:例如,数据分析、图像处理、加密算法等。这些任务通常耗时较长且对 CPU性能要求较高。通过将这些任务委托给Web Worker,可以避免阻塞主线程,从而保持应用的响应性。
  • 异步操作:当需要执行一些异步操作时,例如从服务器获取数据,可以使用Web Worker来避免因为等待异步操作完成而导致的主线程卡顿。
  • 人工智能:Web Worker可以用于处理机器学习模型的训练或推断时的并行计算,从而提高模型的训练速度和响应性。

Web Worker的局限性

  • 兼容性问题:尽管HTML5已经普及,但Web Worker在大多数厂商的浏览器中仅在最新的大版本中支持,在旧版本中支持并不好。这导致开发者在实际项目中可能会放弃使用Web Worker。

  • 资源限制:无法直接访问DOM、同源策略、无法读取本地文件等等。

  • 编程复杂性:使用Web Worker需要处理线程间的通信,这增加了编程的复杂性。对于简单的任务使用Web Worker可能并不划算。

  • 安全性问题:因Web Worker是在后台运行的多线程,所以更隐蔽,由此也带来了新的安全问题:如恶意脚本的注入以利用Web Worker大规模执行多线程攻击来放大攻击效果、恶意创建大量web worker并让它们执行高负载的任务而导致浏览器崩溃、importScripts没有跨域限制可能会加载不受信任的脚本从而导致安全漏洞等等。

Web Worker的通信效率问题

除了以上局限性,Web Worker的通信效率问题也是值得注意的一点。

  • 无法共享内存: 与传统多线程编程不同,Web Worker不能直接共享内存,主页面与worker之间的数据传递的是通过拷贝而不是共享来完成的。因此在如大文件传输场景下可能会消耗大量内存和处理时间。

  • 数据序列化问题: 当主线程与Web Worker之间在数据交换时需要对数据进行序列化和反序列化,序列化会阻塞发送方,而反序列化会阻塞接收方。因此即使是小型数据,也需要经过这一过程。这可能在频繁通信的情况下积累成为性能瓶颈。

  • postMessage:postMessage方法本身并不是导致通信效率低下的主要原因,而是由于如Worker线程需要频繁地向主线程发送大量消息,或者消息体积较大等其他因素造成。这可能会导致主线程处理消息的速度跟不上Worker线程发送消息的速度,从而引起通信拥塞和性能问题。

主线程Web Worker数据传输数据传输postMessage(data)onmessage(event)序列化数据发送序列化数据反序列化数据postMessage(replyData)序列化回复数据发送序列化回复数据反序列化回复数据主线程Web Worker

通信效率带来的问题

由于通信效率的限制,Web Worker不适用于实时任务。由于消息传递的开销和可能的网络延迟,Web Worker无法保证实时性。因此,对于在线游戏、视频会议等一些需要实时响应场景,使用Web Worker可能不是最佳选择。

思考:有了 Web Worker API,JavaScript 是否真的变成了一门多线程语言?

在 MDN 的web worker的”线程安全“一节中提到:

“The Worker interface spawns real OS-level threads”

从底层技术角度来看,Web Worker确实具备多线程的特性。然而这与传统多线程编程语言(如Java或C++)有所不同。如,JavaScript中的主线程与Web Worker之间采用的是消息传递来通信,而不是直接共享内存。这意味着Web Worker之间无法直接共享数据,而传统多线程语言则可以直接共享内存,从而实现更直接和高效的线程间通信。

尽管Web Worker从底层技术上看具备多线程的特性,但如今JavaScript的主要应用领域仍然是处理用户界面和用户交互,Web Worker的引入主要是为了改善前端应用的响应性,使其能够更好地处理一些计算密集型任务,而不是将JavaScript彻底转变为多线程编程语言。

总结而言,尽管Web Worker API为JavaScript提供了一定程度的多线程支持,但JavaScript仍然是一门主要依赖于单线程执行的编程语言,Web Worker并没有改变JavaScript的单线程本质。

js多线程技术的未来展望

未来的js多线程应该具有更好的性能、更好的响应性以及更多的并行计算能力,随着Web技术不断发展,多线程前景越发广阔。如:

  • 浏览器引擎及硬件加速技术的不断发展,使得在浏览器中处理复杂的多线程任务更为可行;
  • WebAssembly等新技术的融合可能带来的机遇;
  • 随着ECMAScript标准的不断发展,可以期待更多多线程相关的功能和API的引入,以更好地支持并行计算。

总结

综上所述,Web Worker作为一种在前端开发中多线程的工具,的确有其独特的优势。然而,我们必须明白,尽管它被广泛视为解决JavaScript单线程问题的一种方式,但它并没有从根本上改变JavaScript的单线程本质。在使用Web Worker时,我们仍然需要面对资源限制、通信开销以及安全性等问题。因此,可以说Web Worker是一种”伪解药“。它有助于缓解JavaScript单线程的限制,但并非银弹。在未来,我们期待JavaScript多线程领域的进一步发展,以实现Web能力的持续提升🚀!


原文链接:https://juejin.cn/post/7274146202496565306
 

这篇关于Web Worker:JS多线程的伪解药?的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/378649

相关文章

python web 开发之Flask中间件与请求处理钩子的最佳实践

《pythonweb开发之Flask中间件与请求处理钩子的最佳实践》Flask作为轻量级Web框架,提供了灵活的请求处理机制,中间件和请求钩子允许开发者在请求处理的不同阶段插入自定义逻辑,实现诸如... 目录Flask中间件与请求处理钩子完全指南1. 引言2. 请求处理生命周期概述3. 请求钩子详解3.1

使用Python获取JS加载的数据的多种实现方法

《使用Python获取JS加载的数据的多种实现方法》在当今的互联网时代,网页数据的动态加载已经成为一种常见的技术手段,许多现代网站通过JavaScript(JS)动态加载内容,这使得传统的静态网页爬取... 目录引言一、动态 网页与js加载数据的原理二、python爬取JS加载数据的方法(一)分析网络请求1

python多线程并发测试过程

《python多线程并发测试过程》:本文主要介绍python多线程并发测试过程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、并发与并行?二、同步与异步的概念?三、线程与进程的区别?需求1:多线程执行不同任务需求2:多线程执行相同任务总结一、并发与并行?1、

SpringBoot项目Web拦截器使用的多种方式

《SpringBoot项目Web拦截器使用的多种方式》在SpringBoot应用中,Web拦截器(Interceptor)是一种用于在请求处理的不同阶段执行自定义逻辑的机制,下面给大家介绍Sprin... 目录一、实现 HandlerInterceptor 接口1、创建HandlerInterceptor实

Web技术与Nginx网站环境部署教程

《Web技术与Nginx网站环境部署教程》:本文主要介绍Web技术与Nginx网站环境部署教程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、Web基础1.域名系统DNS2.Hosts文件3.DNS4.域名注册二.网页与html1.网页概述2.HTML概述3.

Python使用Reflex构建现代Web应用的完全指南

《Python使用Reflex构建现代Web应用的完全指南》这篇文章为大家深入介绍了Reflex框架的设计理念,技术特性,项目结构,核心API,实际开发流程以及与其他框架的对比和部署建议,感兴趣的小伙... 目录什么是 ReFlex?为什么选择 Reflex?安装与环境配置构建你的第一个应用核心概念解析组件

Python多进程、多线程、协程典型示例解析(最新推荐)

《Python多进程、多线程、协程典型示例解析(最新推荐)》:本文主要介绍Python多进程、多线程、协程典型示例解析(最新推荐),本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定... 目录一、multiprocessing(多进程)1. 模块简介2. 案例详解:并行计算平方和3. 实现逻

Nginx使用Keepalived部署web集群(高可用高性能负载均衡)实战案例

《Nginx使用Keepalived部署web集群(高可用高性能负载均衡)实战案例》本文介绍Nginx+Keepalived实现Web集群高可用负载均衡的部署与测试,涵盖架构设计、环境配置、健康检查、... 目录前言一、架构设计二、环境准备三、案例部署配置 前端 Keepalived配置 前端 Nginx

VSCode中配置node.js的实现示例

《VSCode中配置node.js的实现示例》本文主要介绍了VSCode中配置node.js的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着... 目录一.node.js下载安装教程二.配置npm三.配置环境变量四.VSCode配置五.心得一.no

JS+HTML实现在线图片水印添加工具

《JS+HTML实现在线图片水印添加工具》在社交媒体和内容创作日益频繁的今天,如何保护原创内容、展示品牌身份成了一个不得不面对的问题,本文将实现一个完全基于HTML+CSS构建的现代化图片水印在线工具... 目录概述功能亮点使用方法技术解析延伸思考运行效果项目源码下载总结概述在社交媒体和内容创作日益频繁的