Web Worker 是什麼? 可以用在哪?

2026年1月6日

💎 加入 E+ 成長計畫 與超過 900+ 位工程師一同在社群成長,並獲得更多深度的軟體前後端學習資源

在早期的前端開發,會放在前端處理的東西不多,基本上不脫離簡單的事件操作、動畫特效;不過隨著前端發展越來越純熟,開發者在前端做的事情越來越多,當初 JavaScript 的設計就逐漸不足以支應新的需求。

這時前端社群逐漸有了不同的技術,來彌補 JavaScript 做不到的,藉此讓開發者們能在前端做更複雜的操作;在前端開發很常聽到的 Web Worker 與 Service Worker 都在這個範疇中。

Web Worker 是什麼?

Web Worker 的核心概念是開啟另一個執行緒做背景運算,讓複雜運算不會阻塞 JavaScript 的主要執行緒。

要理解這點,需要從歷史的脈絡來看 JavaScript 的發展。最開始 JavaScript 被設計時,那個年代的電腦與瀏覽器,都遠不如現代的強大,所以把 JavaScript 設計成單一執行緒 (single-threaded),每次只能做一件事,基本上沒什麼問題。

但是現代瀏覽器能夠多工,前端開發者可以讓瀏覽器同時處理不同的事情,在這個脈絡下,JavaScript 的單一執行緒設計,就變成某種阻礙,無法有效發揮現代瀏覽器多核 CPU 的運算能力。

具體來說,假如今天有某個比較複雜的運算在跑,其他事情就沒辦法同時被處理;從前端的角度來看,這代表對使用者來說,畫面可能會卡住不動,使用體驗相當不理想。但明明瀏覽器能夠做更多事,所以如果能有一個機制讓複雜的、會卡住 JavaScript 執行緒的那些任務被分擔處理,就能解決這種不理想的使用者體驗。

Web Worker 的存在就是在解決這個問題。我們可以透過瀏覽器的 Web Worker API,去另一個執行緒 (在社群很多人稱之為 Worker Thread) 執行任務;這對 JavaScript 所在的執行緒來說,等同於在背景有另一個幫手幫忙執行任務,所以不會因為要處理運算,就被迫卡著不能做其他事。

可以在這張圖看到,透過 Web Worker,假如今天有某個需要花比較多時間的運算,就先透過 postMessage 放到 Worker 的執行緒做運算;運算完拿到結果後,再傳回主要執行緒,以平行的方式進行處理,這樣就能不阻塞主要執行緒。

Web Worker 的具體使用情境

在談具體的 Web Worker 使用情境時,推薦讀者不要硬背下這些使用情境,而是回到脈絡來思考。Web Worker 的出現是要解決前端複雜運算阻塞主要執行緒,導致畫面卡住的不良使用體驗。

進一步說,使用者做了某個操作,會希望立即得到 UI 的回饋,假如某件事情會導致這種立即回饋無法馬上發生,就可以思考使用 Web Worker,來把卡住的運算,搬到另一個執行緒來處理。

一個常見的使用情境,是在許多圖片管理網站 (例如 Flickr 或 Google Photos),在載入圖片時,會同時去解析圖片拿到圖片的元資料 (meta-data),在這個過程會需要把圖片轉成 ArrayBuffer 的格式,所以需要花時間做運算;這就是能用上 Web Worker 的情境,在 Worker 執行緒處理完後,再把拿到的元資料傳回主要執行緒,就能避免主執行緒阻塞。

特別注意,Web Worker 這種開另一個執行緒處理運算的做法,直觀看起來能讓效能變好,但並非所有情境都是如此。往下讀之前,推薦讀者可以稍微暫停,思考一下多開一個執行緒的取捨。

在使用 Web Worker 時,一個顯而易見的成本是傳遞訊息的成本,以上面提過的這張圖來說,把要處理的東西從主要執行緒,傳給 Worker 執行緒,處理完後再傳回主要執行緒,這每一個步驟雖然不需要花太多時間,但仍是額外的成本。所以假如某個運算,其實很快就能處理完,特別是那種對使用者體驗影響不大的運算,其實可以在主要執行緒處理即可,無需額外丟到 Worker 執行緒處理。

進一步說,加快主要執行緒處理,除了 Web Worker 這個思考角度外,還有其他可以做的方式。例如目前社群中熱門的做法之一,是透過 WebAssembly 把耗時的運算轉由其他語言處理 (例如 Rust),在某些場景下,這會比用 Web Worker 來得更快。

閱讀更多

如果你想了解 Web Worker 如何具體使用,以及 Service Worker 與 Web Worker 的區別,我們在 E+ 的主題文中有更詳細的討論。感興趣的讀者,歡迎加入 E+ 後閱讀 (連結)。

🧵 如果你想收到最即時的內容更新,可以在 FacebookInstagram 上追蹤我們