网络优化初学者难吗_初学者的网络工作者

网络优化初学者难吗

JavaScript是一种单线程语言,这意味着它按顺序执行代码,并且必须先执行一段代码,然后才能继续执行下一段代码。 (JavaScript is a single-threaded language meaning that it executes code in order and must finish executing a piece of code before moving onto the next.)

For HTTP requests, JavaScript provides us with XMLHttpRequest which is non-blocking.But if we have a CPU intensive code in the program, it will block the main thread until it’s done, making UI unresponsive for that period. One way of solving it is to use setTimeout or setInterval. We can break the CPU intensive code into smaller parts and attach timeout with it. While it may work for smaller programs, as code complexity increases it becomes difficult to decide where to add timeout functions. What we need is a separate thread where these calculations are done, hence making the main thread free to handle UI events, manipulate DOM, or do other tasks.

对于HTTP请求,JavaScript为我们提供了非阻塞的XMLHttpRequest,但是如果程序中有CPU密集型代码,它将阻塞主线程直到完成,从而使UI在此期间无响应。 解决它的一种方法是使用setTimeout或setInterval。 我们可以将占用大量CPU的代码分解为较小的部分,并为其附加超时。 尽管它可能适用于较小的程序,但是随着代码复杂度的增加,很难确定在何处添加超时功能。 我们需要一个单独的线程来完成这些计算,从而使主线程可以自由处理UI事件,操纵DOM或执行其他任务。

网络工作者的救援 (Web Workers to the rescue)

HTML5 introduced Web Worker to us. Web Workers are JavaScript programs running on a different thread, in parallel to the main thread. It allows you to put long-running and computationally intensive tasks on the background without blocking the UI, making your app more responsive. Worker utilizes a thread-like message passing between the main script and the background script to achieve parallelism.

HTML5向我们介绍了Web Worker。 Web Worker是在与主线程并行的其他线程上运行JavaScript程序。 它允许您将长时间运行且计算量大的任务放在后台,而不会阻塞UI,从而使您的应用程序具有更高的响应速度。 Worker利用主脚本和后台脚本之间传递的类线程消息来实现并行性。

网络工作者的类型 (Types of Web Workers)

By creating separate threads for parallel JavaScript program Worker thread allows us to achieve multithreading. There are two types of Web Workers.

通过为并行JavaScript程序创建单独的线程,工作线程使我们可以实现多线程。 有两种类型的Web Worker。

Dedicated Workers: Dedicated Web Workers are instantiated by the main process and can only communicate with it.

专用工作者 :专用Web工作者由主过程实例化,并且只能与之进行通信。

Shared Workers: Shared workers can be reached by all processes running on the same origin (different windows, browser tabs, iframes, or other shared workers).

共享工作程序 :在同一源上运行的所有进程(不同的窗口,浏览器选项卡,iframe或其他共享工作程序)都可以访问共享工作程序。

This article will only cover dedicated workers and I’ll refer to them as ‘web workers’ or ‘workers’ throughout.

本文仅涵盖敬业的工作者,在整个过程中,我将其称为“ 网络 工作者 ”或“ 工作者 ”。

入门 (Getting started)

Web Workers run in an isolated thread in the browser. Hence the code they execute is contained in a separate JavaScript file and incorporated in your page by asynchronous HTTP requests. For creating a worker thread we add the following lines on our main page.

Web Workers在浏览器中的隔离线程中运行。 因此,它们执行的代码包含在单独的JavaScript文件中,并通过异步HTTP请求并入您的页面。 为了创建工作线程,我们在主页上添加了以下几行。

var worker = new Worker(‘calculate.js’);

If the “calculate.js” file exists and is accessible, the browser will spawn a new thread that downloads the file asynchronously. Right after the download is completed, it will be executed and the worker will begin. In case the provided path to the file returns a 404, the worker will fail silently.

如果“ calculate.js ”文件存在并且可以访问,则浏览器将生成一个新线程,以异步方式下载该文件。 下载完成后,将立即执行下载并开始工作。 如果提供的文件路径返回404,则工作程序将静默失败。

To start the worker, we have to call a postMessage() method.

要启动工作程序,我们必须调用postMessage ()方法。

worker.postMessage(message, [transfer]);

Here the message is the object to deliver to the worker page. A transfer is an optional array of Transferable objects (we will talk about Transferable objects in a later section).

此处的消息是要传递到工作页面的对象。 传输是Transferable对象的可选数组(我们将在后面的部分中讨论Transferable对象)。

Communication between the web worker and the main page occurs by two methods the postMessage() method and the “message” event handler.

Web Worker和主页之间的通信通过postMessage ()方法和“ 消息”事件处理程序这两种方法进行。

postMessage can accept either a string or JSON object as its single argument. Newer browsers support a JSON object as a first parameter to the method while older browsers support just a string. When a message is sent from postMessage() the other page will receive the event as a ‘message’ event. For error handling, an ‘error’ event is passed.

postMessage可以接受字符串或JSON对象作为其单个参数。 较新的浏览器支持JSON对象作为该方法的第一个参数,而较旧的浏览器仅支持字符串。 从postMessage()发送消息时,另一页将接收该事件作为' message '事件。 为了进行错误处理,传递了一个' error '事件。

In the example above, main.html calls the two web workers (prime and factorial)with postMessage. I have used separate web workers for prime and fibonacci methods, both methods symbolize large computations.

在上面的示例中, main.html使用postMessage调用两个Web工作者(素数和阶乘)。 我使用了单独的网络工作者来进行素数和斐波那契方法,这两种方法都象征着大量的计算。

primeWorker.postMessage({cmd:'first50'});

fibonacciWorker.postMessage({cmd:'first100'});

The worker files are themselves listening to the ‘message’ event and as soon as they receive an event they do their calculations and send the result back with the help of self.postMessage method. I have also added a third button to change the background color, it symbolizes UI changes. When you call prime or factorial from the script an independent parallel web worker thread is spawned which will work on these methods and parallelly you could make changes in UI by clicking the change background button.

工作文件本身正在侦听“ 消息”事件,并且一旦接收到事件,便会进行计算并借助self.postMessage方法将结果发送回去。 我还添加了第三个按钮来更改背景颜色,它象征着UI的更改。 当您从脚本调用素数或阶乘时,会生成一个独立的并行Web工作线程,该线程可在这些方法上运行,并且并行地,您可以通过单击更改背景按钮在UI中进行更改。

In the main.html file, I have added an error event listener also.

main.html文件中,我还添加了一个错误事件侦听器。

fibonacciWorker.addEventListener('error', errorEvent, false);

if an error occurs while a worker is executing, the ErrorEvent is fired. This interface contains three useful properties for figuring out what went wrong: filename — the name of the worker script that caused the error, lineno — the line number where the error occurred, and message — a meaningful description of the error.

如果在执行工作程序时发生错误,则会触发ErrorEvent。 此接口包含搞清楚什么地方出错了三个有用的特性: 文件名 -导致错误,LINENO工人脚本的名称-发生错误的行号,和消息 -错误的有意义的描述。

You must have noticed I have used “self” in prime.js and “this” in fibonacci.js, its because in the context of a worker, both “self” and “this” reference the global scope for the worker.

您一定已经注意到我在prime.js和“ this”中使用了“ self” fibonacci.js中 ,这是因为在工作人员的上下文中,“自我”和“此”均引用工作人员的全局范围。

Here if we haven’t used web workers then the browser would have frozen for the time the fibonacci and prime functions were computing and so you wouldn't be able to interact with UI at that time.

在这里,如果我们不使用网络工作者,那么在斐波那契和主要功能正在计算时,浏览器将被冻结,因此您当时将无法与UI进行交互。

导入脚本和库 (Importing scripts and libraries)

Worker threads can import an external script using the importScripts() method. It accepts zero or more URIs as parameters to resources to import. The browser loads each listed script and executes it. Any global objects from each script may then be used by the worker. If the script can’t be loaded, NETWORK_ERROR is thrown, and the subsequent code will not be executed.

辅助线程可以使用importScripts ()方法导入外部脚本。 它接受零个或多个URI作为要导入的资源的参数。 浏览器将加载并执行每个列出的脚本。 然后,工作人员可以使用每个脚本中的任何全局对象。 如果无法加载脚本,则将引发NETWORK_ERROR ,并且后续代码将不会执行。

importScripts(‘foo.js’); /* imports just “foo.js” */importScripts(‘foo.js’, ‘bar.js’);importScripts('//example.com/hello.js'); 

子工 (Subworkers)

Workers may spawn more subworker thread. This is great for further breaking up large tasks at runtime. However, subworkers have some conditions of their own:

工人可能会产生更多的子工人线程。 这对于在运行时进一步分解大型任务非常有用。 但是,子工作人员有其自身的一些条件:

⦁ Subworkers must be hosted within the same origin as the parent page.

⦁子工作人员必须与父页面位于同一来源。

⦁ URIs within subworkers are resolved relative to their parent worker’s location. This makes it easier for workers to keep track of where their dependencies are.

sub子工作人员中的URI是相对于其父工作人员的位置来解析的。 这使工作人员更容易跟踪其依赖项在哪里。

But while spawning subworkers we have to be cautious about not hogging too many of the user’s system resources.

但是,在生成子工作人员时,我们必须小心不要占用太多用户的系统资源。

嵌入式工作者 (Embedded Workers)

If you want to create a worker script on the fly or don’t want to create separate files for workers. You can embed it all in a single page with the help of Blob and using Data blocks.

如果您想即时创建工作程序脚本,或者不想为工作程序创建单独的文件。 您可以借助Blob并使用数据块将它们全部嵌入到单个页面中。

With Blob(), you can “inline” your worker in the same HTML file as your main logic by creating a URL handle to the worker code as a string.

使用Blob(),您可以通过将工作程序代码的URL句柄创建为字符串,从而将工作程序“内联”到与主逻辑相同HTML文件中。

let blob = new Blob([
"onmessage = function(e) { postMessage('msg from worker'); }"]);// Obtain a blob URL reference to our worker 'file'.
let blobURL = window.URL.createObjectURL(blob);

The magic happens in window.URL.createObjectURL().This method creates a simple URL string that can be used to reference data stored in a DOM File or Blob object. Blob URLs are unique and last for the lifetime of your application(e.g. until the document is unloaded).

魔术发生在window.URL.createObjectURL()中 。此方法创建一个简单的URL字符串,可用于引用存储在DOM File或Blob对象中的数据。 Blob URL是唯一的,并且在您的应用程序的生存期内一直有效(例如,直到文档被卸载为止)。

Now for the clever part. The script element that does not have an src attribute or has a type attribute that does not identify an executable MIME type won’t be parsed by JavaScript(Data block). So we can write our worker code in this script tag and then use Blob to create a URL for the same.

现在为聪明的部分。 JavaScript(数据块)不会解析没有src属性或没有标识可执行MIME类型的type属性的script元素。 因此,我们可以在此script标记中编写我们的工作程序代码,然后使用Blob为其创建URL。

In the example above, in script id “worker-1” I have added the code for web worker and then in JavaScript parsed script created a Blob URL for the same.

在上面的示例中,在脚本ID“ worker-1”中,我添加了针对Web worker的代码,然后在JavaScript解析的脚本中为其创建了Blob URL。

与工作者之间传输数据 (Transferring data to and from Workers)

When we use postMessage we transfer data between web workers and the main page. This data is copied not shared between two pages i.e Objects are serialized as they’re handed to the worker, and subsequently, de-serialized on the other end. Most browsers implement this feature as structured cloning. This seems okay for small data transfer but for large amounts of data, this is a noticeable overhead.

使用postMessage时,我们在Web Worker和主页之间传输数据。 此数据被复制,不能在两个页面之间共享,即对象在传递给工作程序时被序列化,然后在另一端进行反序列化。 大多数浏览器将此功能实现为 结构化克隆 对于少量数据传输,这似乎可以,但是对于大量数据,这是一个明显的开销。

To mitigate this performance hit we can use a Transferrable object. With Transferable Objects, data is transferred from one context to another. It vastly improves the performance of sending data to a Worker. Think of it as pass-by-reference if you’re from the C/C++ world. However, unlike pass-by-reference, the ‘version’ from the calling context is no longer available once transferred to the new context. For example, when transferring an ArrayBuffer from your main app to Worker, the original ArrayBuffer is cleared and no longer usable. Its contents are transferred to the Worker context.

为了减轻这种性能影响,我们可以使用一个Transferrable对象。 使用可传输对象,数据从一个上下文传输到另一个上下文。 它极大地提高了向工作者发送数据的性能。 如果您来自C / C ++世界,可以将其视为传递引用。 但是,与传递引用不同的是,调用上下文中的“版本”一旦转移到新上下文中就不再可用。 例如,当将ArrayBuffer从主应用程序传输到Worker时,原始ArrayBuffer被清除并且不再可用。 其内容已传输到Worker上下文。

To use transferrable objects the following command is used

要使用可转移的对象,请使用以下命令

worker.postMessage(arrayBuffer, [arrayBuffer]);

The first argument is the data and the second is the list of items that should be transferred.

第一个参数是数据,第二个参数是应传输的项目列表。

Web Workers可用的功能 (Features available to Web Workers)

Web Workers have access only to a subset of JavaScript features due to their multi-threaded nature. Here’s the list of features:

由于其多线程特性,Web Workers仅可以访问一部分JavaScript功能。 以下是功能列表:

⦁ The navigator object

⦁导航器对象

⦁ The location object (read-only)

⦁位置对象(只读)

⦁ XMLHttpRequest

⦁XMLHttpRequest

⦁ setTimeout()/clearTimeout() and setInterval()/clearInterval()

⦁setTimeout()/ clearTimeout()和setInterval()/ clearInterval()

⦁ The Application Cache

Application应用程序缓存

⦁ Importing external scripts using importScripts()

using使用importScripts()导入外部脚本

⦁ Creating other web workers

⦁创建其他网络工作者

⦁ Web Worker limitations

⦁Web Worker的局限性

Web Workers don’t have access to some very crucial JavaScript features:

Web Workers无法访问一些非常关键JavaScript功能:

⦁ The DOM (it’s not thread-safe)

⦁DOM(它不是线程安全的)

⦁ The window object

⦁窗口对象

⦁ The document object

document文件对象

⦁ The parent object

⦁父对象

用例 (Use cases)

Web Workers have great powers, but like the saying goes “With great power comes great responsibility”. Similarly, we should be cautious while using them. It should be preferred where background tasks have to be done in parallel to the main UI task or the tasks performed have to be hidden from the user. Some of its other use cases could be:

Web Workers具有强大的力量,但俗话说“ 强大的力量伴随着巨大的责任 ”。 同样,在使用它们时我们应谨慎。 在必须与主UI任务并行执行后台任务或必须向用户隐藏执行的任务时,应该是首选方法。 它的其他一些用例可能是:

⦁ Prefetching and/or caching data for later use.

⦁预取和/或缓存数据以备后用。

⦁ Code syntax highlighting or other real-time text formatting.

⦁代码语法突出显示或其他实时文本格式。

⦁ Spell checker

⦁拼写检查

⦁ Progressive Web Apps

⦁渐进式Web应用

⦁ Analyzing video or audio data.

⦁分析视频或音频数据。

⦁ Background I/O or polling of web services.

⦁后台I / O或Web服务的轮询。

⦁ Processing large arrays or humungous JSON responses.

⦁处理大型数组或庞大的JSON响应。

⦁ Image filtering in <canvas>.

<在<canvas>中进行图像过滤。

⦁ Updating many rows of a local web database.

⦁更新本地Web数据库的许多行。

Please Note: Due to security issues you can’t run your web workers locally on the browser. I used Web Server for Chrome, which worked great.

请注意:由于安全问题,您不能在浏览器上本地运行Web Worker。 我使用了适用于Chrome的Web服务器,效果很好。

Thanks for taking out the time to read the article. In the next article, I will talk about Service Workers, a different but very useful web worker.

感谢您抽出宝贵的时间阅读本文。 在下一篇文章中,我将讨论服务工作者,这是一个不同但非常有用的Web工作者。

翻译自: https://medium.com/javascript-in-plain-english/web-workers-for-beginners-57d7a389cded

网络优化初学者难吗

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值