Web Workers 是浏览器 API 中的一个重要组成部分。它允许 JavaScript 程序在独立的线程中运行,并与主线程进行通信。这使得 Web 应用程序能够更充分地利用多核 CPU,并提高其响应能力。而 Web Components 则允许开发者将组件化思想应用到前端设计中,使得前端组件可以被多个应用程序复用。
本文将介绍如何在 Web Components 中使用 Web Workers,以及为什么要这样做。
Web Workers 的简介
Web Workers 的 API 可以用来在浏览器中创建独立的 JavaScript 线程,它们不与主线程共享内存,因此可以避免阻塞主线程的情况。这意味着程序员可以编写不会干扰界面响应的程序,这可以对于某些应用程序来说是至关重要的。
与主线程不同,Web Workers 中不能直接访问 DOM。它们被设计成无法对页面进行修改,因为这可能会导致不可预测的行为。但是,Web Workers 允许与主线程通信,即通过使用 postMessage() 方法向主线程发送消息,并通过 onmessage 事件监听主线程的回复。
在这里,我们将使用 Dedicated Workers ,这种类型的 Web Workers 可以在不干扰主线程的同时,处理较大的计算任务。因为我们需要一个 Dedicated Worker 的实例来处理一个 Web Component 的所有实例,所以我们再创建一个 Shared Worker 很可能是没有意义的。
Web Components 的简介
Web Components 允许程序开发者将可复用的自定义元素、Shadow DOM 和 HTML templates 打包成组件,这些组件可以通过 import 和 export 与其他组件进行生态系统间的交互。通过 Web Components,代码可以以封装、独立和可重用的方式进行组织和构建,以便将其插入到现有的 Web 应用程序中。
自定义元素
自定义元素使用开发者定义的标签名在 HTML 页面上进行展示。我们只需通过 ES6 的类继承 HTML 元素的构造函数,即可创建一个自定义元素。
<!-- index.html --> <body> <hello-world></hello-world> <script type="module" src="./hello-world.js"></script> </body>
// hello-world.js class HelloWorld extends HTMLElement { constructor() { super(); this.innerText = 'Hello, World!'; } } customElements.define('hello-world', HelloWorld);
当我们在 HTML 页面中引入这个组件时,就会渲染出 "Hello, World!"。
Shadow DOM
Shadow DOM 是在当前 HTML 里面创建一个沙箱 DOM,来隔离当前的 Web Component 和整个 HTML 页面的其他元素之间的变量或样式干扰。具体来说,Shadow DOM 有以下几个功能:
- 将组件的样式封装在其中,防止样式与其他标记干扰。
- 将组件中的样式变量隔离在其中,并与其他组件以及整个 HTML 页面隔离开来。
- 将节点绑定到组件,而不是 Body 上,可以使得组件更加灵活。
<!-- index.html --> <body> <hello-world></hello-world> <script type="module" src="./hello-world.js"></script> </body>
-- -------------------- ---- ------- -- -------------- ----- ---------- ------- ----------- - ------------- - -------- ----- -------- - ------------------------------------------------ ----- ----- - --------------------------------- ----- ---------- - ------------------- ----- -------- --- ------------------------------ - - ------------------------------------------- ------------
-- -------------------- ---- ------- ---- ---------------- --- --------- -------------------------- ------- - - ------ ----- - -------- --------- ---------- -----------
HTML templates
HTML templates 允许我们在 HTML 页面上创建可复用的标记片段,这些标记片段可以从 JavaScript 代码中通过 cloneNode 方法进行创建。这对于我们构建自定义元素以及组合 Web Components 的时候非常有用。
Web Workers 与 Web Components 结合使用
我们可以将 Web Workers 与 Web Components 结合使用,以使我们的组件更加响应灵活,不浪费大量的系统资源。
如果我们有一个 Web Component,其需要长时间运行大量的计算,并其中有很多个实例,那么这些计算任务很可能会阻塞主线程并导致页面无法响应。我们可以将这些计算任务放在 Dedicated Web Workers 中进行处理,以充分利用资源并保持程序的响应速度。
接下来,我们将构建一个 Web Component,用于计算斐波那契数列。斐波那契数列生成数字的计算是一种效率非常低的操作,必须由 Dedicated Worker 进行处理以避免浏览器无响应。
实现计算斐波那契数列的 Dedicated Web Worker
在工作线程中,我们实现了一个计算斐波那契数列的数列生成函数。
-- -------------------- ---- ------- -- --------- -------------- - ----------- - ----- ----- - ------------- ----- --- - ----------- ----- ------ - --- --- - - -- - - -- -- --- ---- - - -- - - ---- ---- - -- -- -- ------ - --------------- - - - - - -- - - -- - - -- - -------------------- ------------- -
在 Web Component 中启动 Dedicated Web Worker
当用户在 Web Component 中输入一个范围,请启动一个 Dedicated Worker 来计算斐波那契数列。斐波那契数列的输出将在 Web Component 内的列表中显示。
-- -------------------- ---- ------- ---- ------------------------ --- --------- ---------------------------------- ------- --- -------- ------------- ------------- -------- - ----- ---------- ------ ---------------- ------------- ------- ---------- ------ -------------- ------------- ------- --------- ------- -------------------------------- --- ---------------------- -----------
-- -------------------- ---- ------- -- ---------------------- ----- ------------------ ------- ----------- - ------------- - -------- ------------------- ----- ------ --- ----- -------- - -------------------------------------------------------- ----- ----- - --------------------------------- ----------------------------------- ----- ---------- - ---------------------------------------------- ----- -------- - -------------------------------------------- ----- ----------- - ----------------------------------------------- ----- ---------- - ---------------------------------------------- ------------------------------------- -- -- - ----- ----- - -------------------------- ---- ----- --- - ------------------------ ---- -- ------ -- - -- --- - ------ - -------------------- - ----------------- ----- ------ - --- ------------------------------ -------------------- ------ ------ ---- --- --- ---------------- - --- -- - -------------------- - --- -------------------- -- - ----- -- - ----------------------------- ------------ - ---- --------------------------- --- ------------------- -- - --- - - --------------------------------------------------- --------------------
在这里,我们使用了 Dedicated Web Worker 来计算斐波那契数列,并在 Web Component 中显示其结果。当用户输入了范围并单击了 “Start” 按钮时,Web Component 将启动 Dedicated Web Worker 。该 Worker 将计算斐波那契数列,并通过 postMessage() 在主线程中发布其结果。在消息处理程序中,Web Component 将在 ul 中显示斐波那契数列。
总结
Web Components 和 Web Workers 都承诺让前端更加模块化、响应式并且具有更高的灵活性。使用 Web Workers 可以避免主线程的阻塞,从而改善应用程序的性能。本文中我们介绍了如何在 Web Components 中使用 Web Workers。掌握这个技术,可以让您构建出更加复杂的 UI 组件,并让它们运行得更加平滑高效。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/6461efe0968c7c53b03452f1