Web Worker 使用筆記

簡介

  • JavaScript 是單執行序的程式語言,若是有複雜的運算時,可能會導致畫面載入緩慢卡頓,降低用戶體驗
  • 借助瀏覽器的 Web Wroker,可以在背景執行緒(Thread)中獨立做這些複雜運算,不干擾 Main Thread (UI Thread)的運行
note-img

功能

多線程處理

  • 允許創建一個獨立的工作線程來執行重量級的計算,從而避免阻塞主執行緒

異步執行

  • Web Worker 運行於與主執行緒隔離的環境中,因此它們的操作是異步的,不會干擾主執行緒的運行

消息傳遞

  • 主執行緒和 Web Worker 之間通過消息傳遞進行溝通

獨立作用域

  • Web Worker 擁有自己的全局變量和函式,不與主執行緒共享作用域

需注意的點

無法訪問 DOM 元素

  • 無法讀取或修改網頁的 HTML
  • 無法使用document,window,parent這些物件

無法共享狀態

  • 無法讀取其他執行緒的資料,需使用postMessage, onmessage方法來和其他執行緒溝通

如何使用

  • 創建主要 JS 檔案:main.js
  • 創建 Web Worker 檔案:worker.js
  • 在主線程創建一個Worker
// main.js// 確認瀏覽器是否支援if (window.Worker) {  const myWorker = new Worker('worker.js')  // 傳送資料給worker  myWorker.postMessage('Hello Worker')  // 接收來自worker的資料  myWorker.onmessage = function (e) {    console.log('Message received from worker: ' + e.data)  }}
  • worker.js中,使用onmessage接收到main.js傳遞的資料
  • 執行完後,在使用postMessage傳回到main.js
// worker.jsonmessage = (e) => {  console.log('Message received from main script')  const workerResult = `Result: ${e.data}`  console.log('Posting message back to main script')  postMessage(workerResult)}

範例

  • 如果要加密一些資訊時,可放到 Web Worker 處理
  • 把輸入資料轉換成 Base64 編碼(模擬加密)
  • Github Repo 參考
// main.jsdocument.getElementById('encrypt').addEventListener('click', () => {  const inputData = document.getElementById('inputData')  const resultDisplay = document.getElementById('result')  const data = inputData.value  if (!data) {    resultDisplay.textContent = '請輸入要加密的資料'    return  }  const worker = new Worker('worker.js')  worker.postMessage(data)  worker.onmessage = (e) => {    resultDisplay.textContent = e.data    worker.terminate()  }  // 監聽Worker是否發生錯誤  worker.onerror = (e) => {    console.error('Worker 錯誤: ', e)    resultDisplay.textContent = '加密過程中發生錯誤'  }  // 完成任務後關閉  worker.terminate()})
// worker.jsonmessage = function (e) {  postMessage(encryptData(e.data))}function encryptData(data) {  return btoa(data)}

第三方 JS 檔案處理

使用 Partytown

note-img

簡介

  • 是一個專為提高網站性能而設計的 JavaScript 函式庫,簡化了使用 Web Worker 的方法
  • 引入第三方 JS 函式庫時,為避免主線程阻塞,可以用這個套件幫我們把這些任務放到 Web Worker 當中處理
  • 不適合用在需要即時與 DOM 交互的 JS 函式庫

適用情境

  • Google Tag Manager (GTM)
  • Google Analytics (GA)
  • Facebook Pixel...

範例:在個人網站加入 GA 效能差異

  • 使用 PageSpeed 測試,Total Blocking Time 減少

Total Blocking Time: 總封鎖時間 (TBT) 指標

  • 是測量首次顯示內容所需時間 (FCP) 之後,主執行緒封鎖一段時間,防止輸入內容回應的總時間

使用 Partytown 之前

note-img

使用 Partytown 之後

note-img

參考資料

# Web # 效能 # Web Worker