Web Worker在項目中的妙用

最近在項目中遇到了一些性能問題,爲了防止圖片一張一張加載而影響體驗和爲了提升效率,須要不斷的提早加載數據和大量圖片,當時咱們在項目中使用worker來作性能優化,把計算量比較大和圖片的預加載放入worker中操做。node

什麼是 worker

經過使用Web Worker, 咱們能夠在瀏覽器後臺運行Javascript, 而不佔用瀏覽器自身線程。Web Worker能夠提升應用的整體性能,而且提高用戶體驗。若是你對worker還不熟悉,請參照,在此就不作過多的介紹了,本文主要是介紹worker的應用場景和性能問題。ajax

如何使用worker預加載圖片

圖片預加載問題分析

  • 通常在項目中不會使用worker來預加載圖片,而是考慮如何實現懶加載圖片,可是基於業務須要因此才使用worker來預加載圖片;預加載圖片可能你用不着,可是本文應該對你瞭解worker有很大幫助;
  • 加載圖片咱們有不少方案(不全,若是你還有其餘方案但願分享):
    • 經過操做DOM裏面的Img標籤來加載圖片。
    • 也能夠經過js的Image對象來加載。
    • 還能夠經過ajax來加載。
  • 經過不斷操做DOM來加載圖片是最耗費資源也是最慢的一種方案;經過Image對象來加載比較耗內存並且也會佔用主線程的資源;把圖片加載放在worker裏面來加載確定是最合適的,可是在子線程裏不能操做DOM,因此Image對象也不能使用,只能考慮使用ajax來實現了,很慶幸的是無論用哪一種方案加載圖片都不存在跨域問題。

具體應用

單獨啓動一個worker來加載圖片,每一次請求回來的數據中都經過postMessage給worker,很少說廢話了,直接貼代碼:跨域

  • Index.js中啓用worker
let w = new Worker("js/workers.js");
 w.onmessage = function (event) {
   /*var img = document.createElement("img");
    img.src = window.URL.createObjectURL(event.data);
    document.querySelector('#result').appendChild(img)
    */
    console.log(event.data);
 };

 w.onerror = function(e){
     e.currentTarget.terminate();
    console.log('erro: ' + e.message);
};複製代碼
  • worker.js中請求圖片
let arr = [...好多圖片路徑];
for (let i = 0, len = arr.length; i < len; i++) {
    let req = new XMLHttpRequest();
    req.open('GET', arr[i], true);
    req.responseType = "blob";
    //req.setRequestHeader("client_type", "DESKTOP_WEB");
    req.onreadystatechange = () => {
      if (req.readyState == 4) {
      // postMessage(req.response);
    }
  }
  req.send(null);
}複製代碼

總結很重要

  • 在worker中使用XMLHttpRequest和在主線程中使用XMLHttpRequest的性能比較,週末特地用node爬了某網站的500多張圖片的url來作測試得出如下結論:
    • 在主線程中每啓動一個XMLHttpRequest請求都會消耗資源,雖然在請求過程當中瀏覽器另外開了一個線程,可是在交互過程當中仍是須要消耗主線程資源;而使用worker則不會過多佔用主線程,只是啓動worker過程時比較耗資源。
    • 大量的XMLHttpRequest請求時,當網速慢時worker中使用XMLHttpRequest和在主線程上使用XMLHttpRequest感覺不到阻塞,當網速很快時大量請求返還時會出現卡頓現象。
  • 在使用worker的過程當中發現,若是worker實列引用爲0,該worker空閒後當即會被關閉;若是worker實列引用不爲0,該worker空閒也不會被關閉。瀏覽器

    ​​

相關文章
相關標籤/搜索