Web Worker没有使用场景?那只是你没有用到而已🐒🐒🐒

前几天的一场面试中,被面试官吐槽了一下,我在我项目中直接使用 Prettier 来做代码格式化,首先加载该依赖包就需要一定的成本了,况且格式化的过程中可能需要一些计算,会导致阻塞整个浏览器。

在这里,我个人目前能想到的就两种方案,一种是使用网络请求的方式,也就是将这个问题抛给后端去处理,后端处理的话也是用相同的办法去做,只是最终把结果返回给前端。因为在浏览器的事件循环中,网络请求并不会阻塞 js 主线程。

还有一个方法就是使用 web worker,将需要格式化或转换的代码交给 worker 去处理,处理完成之后最终把结果返回。

什么是 Web Worker

Web Worker 是一种在浏览器中运行 JavaScript 代码的机制,它允许您在后台线程中执行一些任务,而不会阻塞主线程。主线程通常用于处理用户界面的交互和渲染,而 Web Worker 可以用于执行一些耗时的计算、网络请求、数据处理等任务,以提高应用的性能和响应速度。

它的主要特点是能进行并行计算,他允许在后台同时运行多个线程,这些线程可以并行执行任务。这使得可以同时处理多个耗时的操作,而不会阻塞用户界面。

Web Worker 的使用

首先,您需要创建一个单独的 JavaScript 文件,这将是我们的 Web Worker 文件。例如,我们可以创建一个名为 worker.js 的文件,并编写如下代码:

js 复制代码
// worker.js

self.addEventListener("message", (event) => {
  // 在这里执行后台任务
  const data = event.data;
  const result = doSomeHeavyWork(data);
  self.postMessage(result);
});

function doSomeHeavyWork(data) {
  // 执行耗时的计算或任务
  return data * 2;
}

在主线程代码 JavaScript 代码中,我们可以创建一个 Web worker 实例,然后通过消息传递与他进行通信:

js 复制代码
// 在主线程中
const worker = new Worker("worker.js");

// 发送消息到 Web Worker
worker.postMessage(42);

// 监听从 Web Worker 返回的消息
worker.addEventListener("message", (event) => {
  console.log("接收到 web worker 返回的信息:", event.data);
  worker.terminate();
});

在上述的代码中,使用 addEventListener 监听 message 事件,然后在事件处理程序中执行后台任务。使用 self.postMessage 向主线程发送结果。

在主线程代码中,可以通过使用 postMessage 方法向 Web Worker 发送消息。

最终代码允许结果如下所示:

如何在项目中使用

首先先来说明一下的我自己的情况,我最终在开发一个在线代码协同编辑器,Github 地址 在整个项目中,我们难免会用到一些代码转换或者代码格式化,那么我们这里可以通过使用 Web Worker 的方式来对其进行处理,最终把结果返回给 JavaScript 主线程。

在这篇文章中我们主要是讲解如何将 scss 代码转换成 css 代码。

要想使用,我们首先需要 sass 模块:

bash 复制代码
pnpm add sass

首先我们创建一个 compiler.ts 文件作为 worker 文件,代码如下所示:

ts 复制代码
import * as sass from "sass";

self.onmessage = (event) => {
  const scssCode = event.data;

  try {
    const result = sass.compileString(scssCode);

    self.postMessage({ compiledCss: result.css });
  } catch (error: any) {
    self.postMessage({ error: error.message });
  }
};

它接收从主线程发送的 SCSS 代码,使用 sass 包进行编译,然后将编译后的 CSS 或错误消息发送回主线程。

在我们的 App.tsx 文件中编写以下代码,如下所示:

tsx 复制代码
import React, { useState } from "react";

const App = () => {
  const [scssCode, setScssCode] = useState<string>(
    `
    $primary-color: #3498db;
    
    .button {
      background-color: $primary-color;
      color: white;
      padding: 10px 20px;
      border: none;
      cursor: pointer;
      
      &:hover {
        background-color: darken($primary-color, 10%);
      }
    }
    `
  );

  const compileScss = () => {
    if (!scssCode) return;

    const worker = new Worker(new URL("./compiler.ts", import.meta.url), {
      type: "module",
    });

    worker.onmessage = (event) => {
      if (event.data.error) {
        console.error(event.data.error);
      } else {
        setScssCode(event.data.compiledCss);
      }
      worker.terminate();
    };

    worker.postMessage(scssCode);
  };

  return (
    <div>
      <code
        style={{
          background: "black",
          color: "white",
          height: "200px",
          width: "200px",
          display: "block",
        }}
      >
        {scssCode}
      </code>
      <button onClick={compileScss}>编译代码</button>
    </div>
  );
};

export default App;

在这段代码中我主要做的事情是我偷了个懒哈哈哈哈哈。

我把我们要编写的 scss 代码事先编写好了并通过 worker.postMessage(scssCode) 的方式向 web worker 发送 scss 源代码,并使用 worker.onmessage = event => { ... } 来监听 Web Worker 返回的消息。如果返回的消息包含编译后的 CSS,则更新 scssCode 的状态以显示编译后的 CSS。

首先请看原图,这是我们没有编译过的代码,如下图所示:

当我们点击编译按钮,它会显示被编译后的代码,也就是 css 代码:

大功告成,这个方法运用得好,说不定就成为了你项目中的亮点呢。

总结

通过这种实现方式结合了前端技术,为用户提供了一个简单的在线 SCSS 编译工具。通过将耗时的编译操作放在 Web Worker 中执行,保持了用户界面的流畅性,并提供了实时的编译反馈。

最后分享两个我的两个开源项目,它们分别是:

这两个项目都会一直维护的,如果你也喜欢,欢迎 star 🥰🥰🥰

相关推荐
passerby606115 分钟前
完成前端时间处理的另一块版图
前端·github·web components
掘了23 分钟前
「2025 年终总结」在所有失去的人中,我最怀念我自己
前端·后端·年终总结
崔庆才丨静觅26 分钟前
实用免费的 Short URL 短链接 API 对接说明
前端
崔庆才丨静觅1 小时前
5分钟快速搭建 AI 平台并用它赚钱!
前端
崔庆才丨静觅1 小时前
比官方便宜一半以上!Midjourney API 申请及使用
前端
Moment1 小时前
富文本编辑器在 AI 时代为什么这么受欢迎
前端·javascript·后端
崔庆才丨静觅2 小时前
刷屏全网的“nano-banana”API接入指南!0.1元/张量产高清创意图,开发者必藏
前端
剪刀石头布啊2 小时前
jwt介绍
前端
爱敲代码的小鱼2 小时前
AJAX(异步交互的技术来实现从服务端中获取数据):
前端·javascript·ajax
Cobyte2 小时前
AI全栈实战:使用 Python+LangChain+Vue3 构建一个 LLM 聊天应用
前端·后端·aigc