JavaScript Web Workers

JavaScript 本質上是一門「單執行緒」(Single-threaded) 的語言,這意謂著在瀏覽器中所有的程式碼都在同一個執行緒(主執行緒)上執行。

如果你的網頁需要進行非常大量的計算(例如:圖片過濾、大數據分析、複雜的加密運算等),主執行緒就會被阻塞,導致網頁畫面凍結、使用者無法點擊任何按鈕,這就是所謂的「卡頓」。

Web Workers 的出現,就是為了讓 JavaScript 也能在背景執行緒中運行任務,而不干擾主執行緒的 UI 渲染。

Web Workers 的特點

  1. 獨立執行緒: Worker 在完全獨立於主執行緒的環境中執行。
  2. 不阻塞 UI: 即使 Worker 正在進行耗時運算,使用者依然可以流暢地操作網頁。
  3. 無 DOM 存取權: 為了安全性與平行處理的一致性,Worker 內部無法直接存取範 DOM、window 或 document
  4. 透過訊息通訊: 主執行緒與 Worker 之間透過 postMessage() 發送訊息,並透過 onmessage 接收訊息。

基本用法

建立 Worker 檔案 (worker.js)

首先,我們將耗時的邏輯放在一個獨立的檔案中:

// worker.js
self.onmessage = function (e) {
  console.log('Worker: 收到主執行緒訊息');
  const num = e.data;

  // 模擬繁重運算
  const result = fibonacci(num);

  console.log('Worker: 運算結束,傳回結果');
  self.postMessage(result);
};

function fibonacci(n) {
  if (n <= 1) return n;
  return fibonacci(n - 1) + fibonacci(n - 2);
}

在主程式中啟動 Worker

// main.js
if (window.Worker) {
  const myWorker = new Worker('worker.js');

  // 發送資料給 Worker
  myWorker.postMessage(40);

  // 接收來自 Worker 的結果
  myWorker.onmessage = function (e) {
    console.log('主執行緒: 收到 Worker 回傳結果 ' + e.data);
  };

  myWorker.onerror = function (error) {
    console.log('Worker 發生錯誤: ' + error.message);
  };
}

什麼時候該用 Web Workers?

並非所有任務都需要 Worker,因為建立 Worker 本身也有開銷。適合使用的場景包括:

  • 大量數值計算: 像是加密、解密、物理引擎模擬。
  • 大數據排序與過濾: 當前端需要處理數萬條資料時。
  • 圖片與影片處理: 例如即時套用圖片濾鏡。

總結

Web Workers 是開發具有流暢體驗的現代 Web 應用不可或缺的技術。當你發現某個函式執行超過 100ms 導致網頁有明顯延遲時,將該邏輯移往 Web Worker 就是通往 2025 高效能網頁的最佳實踐。