在过去几年中,在浏览器中运行的JavaScript应用程序的性能显着提高。这主要是由于对实际执行代码的底层JavaScript引擎(例如V8)的持续工作 。但随着这些JavaScript引擎变得更快,我们的Web应用程序也需要更多。
像File API这样的JavaScript API的引入使得编写在客户端执行一些严肃的计算任务的JavaScript应用程序成为可能。尽管JavaScript引擎有所改进,但由于浏览器通过资源密集型任务工作,因此用户遇到冻结用户界面的情况并不少见。这会导致糟糕的用户体验。Web Workers的目的是为开发人员提供一种指导浏览器在后台处理大型任务的方法; 因此阻止UI冻结。
在这篇博文中,您将学习如何使用Web Workers构建多线程JavaScript应用程序。让我们潜入!
Web工作者和线程简介
您编写的JavaScript代码通常在单个线程中执行。线程就像一个大的待办事项清单。您编写的每个语句都作为任务添加到列表中,浏览器通过此列表逐个执行每个任务。单线程体系结构的问题在于,如果某个特定任务需要很长时间才能完成,那么在该任务完成之前,其他任务都会被阻止。这称为阻塞。在客户端JavaScript应用程序的世界中,使用单线程架构可能会导致您的应用程序变得缓慢甚至完全没有响应。
Web Workers提供了一种工具,用于创建用于执行JavaScript代码的新线程。有效地创建一个多线程体系结构,浏览器可以在其中同时执行多个任务。创建用于处理大型任务的新线程可以确保您的应用程序保持响应并且不会冻结。
查看 此演示 ,了解使用web worker可能产生的性能影响的示例。首先将工人数量设置为“禁用”,并记录绘制图像所需的时间。然后将工人数设置为“1”并再次运行演示。您应该看到绘制图像所需的时间差异很大。如果你使用更多的工人,它会变得更快。
既然您已经了解了Web工作者在JavaScript应用程序中所扮演的角色,那么我们来看看如何在自己的项目中使用它们。
创建Web Workers
创建Web Workers是一项相当简单的任务。首先,您需要创建一个新的JavaScript文件,其中包含您希望web worker执行的所有代码。然后创建一个新Worker
对象,将路径传递给包含web worker要执行的代码的文件。
var worker = new Worker('work.js');
创建web worker后,可以使用该postMessage()
功能将其激活。稍后在本博文中,您将学习如何使用此函数将数据传递给Web worker。
worker.postMessage();
而已!您现在有一个正在运行的Web worker,它在自己的线程中执行代码。
注意:创建web worker将生成消耗系统资源的实际操作系统级线程。请注意,这会影响用户整个计算机的性能,而不仅仅是Web浏览器。
与Web Worker进行通信
所以你现在知道如何创建Web Workers,但是为了能够在实际应用程序中使用它们,你需要知道如何在主应用程序和Web worker之间传递数据。你使用消息来做到这一点。这些消息可以是简单字符串或JavaScript对象。
要将一些数据从主应用程序发送到Web worker,请在postMessage()
worker对象上调用该函数。
/ *文件:main-script.js * / var worker = new Worker('respond.js'); worker.postMessage('Hello World');
您现在需要在工作脚本中编写一些代码来监听和处理来自主应用程序的消息。在工作脚本中,您将为事件设置事件侦听器message
。
/* File: respond.js */ // Setup an event listener that will handle messages sent to the worker. self.addEventListener('message', function(e) { // Send the message back. self.postMessage('You said: ' + e.data); }, false);
在此示例中,web worker将文本“You said:”添加到原始消息中并将其发送回应用程序。从web worker内部发送数据时,您仍然使用该postMessage()
功能,但这次您打开该功能self
。
最后一步是在原始应用程序中设置一个事件监听器,它将监听web worker发送的消息。
/* File: main-script.js */ var worker = new Worker('respond.js'); // Setup an event listener that will handle messages received from the worker. worker.addEventListener('message', function(e) { // Log the workers message. console.log(e.data);}, false); worker.postMessage('Hello World');
此示例中的事件侦听器将简单地将消息从worker转发到控制台。整个沟通如下:
Application (to worker): Hello World Worker: You said: Hello World Application (to console): You said: Hello World 终止web worker
完成工作后,可以通过调用terminate()
工作对象上的函数来终止它。要让worker自行终止,您需要调用该close()
函数self
。
// Terminate a worker from your application. worker.terminate(); // Have a worker terminate itself. self.close();
您应该始终负责任地使用web worker,并在他们完成执行给定任务后终止他们。这有助于释放用户计算机上其他应用程序的资源。
Web worker的局限性
webworker很棒,但他们确实有一些限制。
同源政策
必须从与尝试创建工作程序的脚本相同的域中提供所有工作程序脚本。这也适用于协议。例如,https://
页面无法调用使用的web workerhttp://
。
限制访问
由于您的Web Workers在主应用程序线程之外运行,因此它们与主应用程序不具有相同的JavaScript功能访问权限。你的工人也没有无法访问:
- DOM
- 该
document
对象 - 该
window
对象 - 该
parent
对象
如果您使用worker来处理最终需要更新主用户界面的任务,则需要使用消息传递系统在worker和主应用程序之间传递数据。然后主应用程序负责更新UI。同样,如果您的web worker需要访问来自或对象的数据document
,则需要在用于启动工作程序的调用中发送该数据。window
parent
postMessage()
受限制的本地访问
如果直接从文件系统(使用file://
)提供网页,Web Workers将无法工作。相反,您将需要使用本地开发服务器,如XAMPP。
最后的想法
Web Workers是HTML5的核心部分。它们使我们能够创建可以利用客户端的功能并利用梦幻般的新技术的应用程序,而无需担心减少最终用户的体验。
虽然网络工作者已经存在了几年,但开发人员社区的采用可悲地受到了限制。使用web worker可以对Web应用程序的性能产生重大影响; 而响应更快的应用程序往往会带来更快乐的用户。我不认识任何不希望用户在使用他们的产品时获得良好体验的人
转载请注明:XAMPP中文组官网 »