DEV Community

Cover image for Web Workers 調用 API,減輕主執行緒負擔
Let's Write
Let's Write

Posted on Edited on Originally published at letswrite.tw

Web Workers 調用 API,減輕主執行緒負擔

本篇要解決的問題

這陣子,不知道是不是演算法的關係,看到的文章很常出現「Web Workers」這個詞,查了一下後發現,Web Workers 是一個連 IE10 都支援的功能,看來是歷史悠久牌子老、街頭巷尾都稱讚的 API,就想說來看一下。

看完幾篇教學文,發現應該再早點知道的,可以處理工作上遇到的一些問題。

Web Workers 可以解決的問題,August 想到的有以下:

  • 調用回應時間比較長的 API
  • 在背後收集使用者的行為
  • 想提前載入頁面上其它區塊會需要的資料

總之,就是可以把一些處理時間較長、不必要在頁面一載入就撈取的資料,丟給另一條執行緒去處理,不讓主執行緖有阻塞,進而減少使用者在操作上會有的卡頓感。

本篇會先簡單說明什麼是 Web Workers,接著是使用方法,以及附上 August 最想應用的方式:調用 API 的 Demo。


簡單解釋 Web Workers

本段最後會提供的參考資源,把 Web Workers 都解釋得很清楚了,所以這段的說明,會用 August 的方式來簡單形容。

我們假設瀏覽器是一間便利商店,這間便利商店因為慣老闆的原因(咦?),只有一位員工,這位員工就是 JS 的主執行緒。超商員工是很辛苦的,又要上架商品、又要結帳、又要煮咖啡、又要幫顧客找網購的商品,然後薪水才這麼一點(哎這樣說好嗎?)

通常,「找網購商品」這件事是耗時最久的,因為員工要在一堆的包裹裡找到特定顧客的那件,耗掉的時間有可能會阻礙結帳,讓結帳的人流排到店門口。而這件事就是網頁上最常發生的調用 API,是不是很像?在 API 回應我們特定需要的資料前,我們就只能等,還什麼事情都不能做。

後來,老闆覺得這樣累績負面評價有害公司的名聲(如:讀取時間會影響 SEO 排名),所以他選擇了最快的解決方式:再找一位員工來,讓他在後面協助處理找包裹這件事,如果煮咖啡也覺得久,那就讓他順便處理煮咖啡好了。這位新來的員工,就是這篇在講的 Web Workers。

Web Workers,就是在網頁上除了 JS 主執行緒之外的另一條執行緒。

參考資源:


Web Workers 使用

Web Workers 的使用方式很簡單,整理成下圖:

Web Workers 使用說明

網頁的 JS 跟 Web Workers 溝通的方式就是 postMessageonmessage

postMessage 是傳送資料。

onmessage 是接收資料。

我們先看網頁上的主要 JS,我們命名為 main.js。

main.js

const worker = new Worker('worker.js');

// 傳送資料
work.postMessage({ name: 'August' });

// 接收 Web Workers 來的資料
worker.onmessage = e => {
  const data = e.data;
  console.log(data);
}
Enter fullscreen mode Exit fullscreen mode

接著來看 Web Workers 的內容,我們命名為 work.js。

work.js

importScripts('https://cdnjs.cloudflare.com/ajax/libs/axios/1.6.0/axios.min.js');

// 接收資料
self.onmessage = e => {
  const data = e.data;
  if(data) {
    const result = axios.post(...); // 調用 API
    self.postMessage(result); // 傳送資料
  }
}
Enter fullscreen mode Exit fullscreen mode

是的,你沒看錯,我也沒寫錯,work.js 在 importScript 時,可以引用 CDN,而且寫程式的方式可以用 ES6。

這點因為看的教程上都沒有,是問了 ChatGPT 後,再透過實作去嘗試才知道的。


Web Workers 使用範例:調用 API

最後這段,是 August 寫了一個 Demo,讓 Web Workers 來處理調用 API 的部份,然後回傳給主執行緒,讓網頁上呈現結果。

完整的原始碼已放上 GitHub,不過有一段 August 想列出來,就是 Web Workers 處理 API 的部份。

原本 August 自己寫了一個,結果丟給 ChatGPT 看,想問它還有沒有可以優化的地方,殊不知,它就給了一個加上「限制最大請求數」的方式,覺得這樣子的方式更符合實際需求,就採用了。


Demo、原始碼

本篇的 Demo 跟原始碼,都放上 GitHub,取用前請分享此篇文章,或對 GitHub 專案點個星星,你的小小舉動,對本站都是大大的鼓勵。

Demo:https://letswritetw.github.io/letswrite-web-workers/

原始碼:https://github.com/letswritetw/letswrite-web-workers

Top comments (0)