Web Workers 學習

前陣子在研究Web Audio API時,發現檔案一多,在解碼和資料的處理就會很慢,查了一下原因主要是因為javascript的單執行緒造成的,所以找到了Web Workers這個東西,可以用來開多執行緒,分擔一些工作;不過研究到最後,並沒有應用到我想解決的問題上,因為Web Workers天生有一些限制在。

Web Workers主要是用來解決比較複雜的運算問題,所以它限制不能做DOM的操作,同時,或是像Web Audio API這種不完全在主執行緒工作的應用也是不能放進Workers的,Web Audio API的多執行緒後來由Google提出的Worklet來處理;那麼Workers到底具體來說可以做什麼事呢 ,我嘗試做了一個實驗,就是在檔案上傳時,先不真的傳到資料庫,而是把檔案先編碼成base64的長字串格式放在Src中,藉此來直接前端啟用播放音樂的功能,這中間最花時間的就是檔案編碼的工作了,所以我把這個工作交給Workers去處理,並比較效益。

就最原始的寫法來說,直接在前端接收使用者選擇的檔案後,new一個fileReader出來,接下來讀檔,編碼再寫回網頁,因為是用迴圈逐一執行的,雖然fileReader.onload是非同步進行的,但是進行編碼時是會佔住主執行緒的資源的,因此其它的檔案就只能等主執行緒空出時間來才能進行,以一次讀進一整張專輯十二首歌來算,平均要花1.66秒才能完成全部的讀檔及編碼的工作。

改成用Workers後,第一個實驗是在主執行緒原本的迴圈中直接開Worker出來,然後把檔案丟進worker去處理,等於是同時開了十二個Workers,這樣跑下來,平均時間縮短到0.86秒,每個worker平均只花33亳秒就完成讀檔及編碼的工作,最花時間的地方是在主執行緒收到Worker回傳的資料後要寫入網頁時,因為這時候主執行緒會依照收到的資料逐一寫入網頁,寫完一筆資料,再寫下一筆,所以卡住了。

最後再做修改,把選擇的檔案清單直接交給一個主要的Worker,由這個Worker去決定要開多少個Worker來讀出檔案及編碼,最後所有資料都回傳給主Worker後,再一次性的回傳給主執行緒來處理,這樣做的話,平均時間縮短到0.24秒,執行緒的總工作時間大概是0.19秒,也就是說,如果主執行緒不要去管多個工作的排程問題的話,單純收到資料並寫入網頁,其實可以很快,而Worker就是在分擔主執行緒的工作這方面發揮了很大的作用。

除了這個簡單的小實驗,另外一個可以嘗試的方式是結合Canvas來使用,動畫或遊戲經常需要大量的計算,可以透過Workers來分擔計算的工作,主執行緒只需要專注最後畫面的呈現就可以了,關於Canvas的應用,我打算過陣子有空找個題目來實作,到時除了Web Workers的應用,還會結合offScreenCanvas這個實驗中的API來試試。




Canvas 學習心得 及 全彩色盤的製作

最近因為工作上的需要,花了點時間研究一下Canvas的使用,目前許多工作職缺強調HTML5的,大多指的是對Canvas或video這類新標籤的熟悉,Canvas是一個畫布系統,採點陣圖的方式來呈現,搭配javascript後,除了簡單的平面圖形之外,也可以拿來做成動畫或遊戲。

我的練習是從做一個網頁小畫家開始的,一開始的功能還算簡單,畫畫線條,改改顏色什麼的都還不難,後來想到選顏色這件事是否能直接用Canvas來做一個時,花了我不少時間,一開始採用計算顏色然後畫出來的方式,感覺顏色怪怪的,研究後發現無法單畫一個點,內建函式提供的指令中沒有單獨畫一個點的功能,至少是兩點一線或是矩形,後來一路研究下去,發現要直接去操作Canvas的象素單位陣列,這牽涉到Canvas的原理是把一張畫布上的每個點的色彩資訊以一維陣列的方式展開的,為了製作這個陣列,我得把原本用來算色盤的HSL色系再改成RGB的色系再寫回去陣列才可以,所以我又花了時間研究色彩系統的轉換公式,最後是stackoverflow上找現成的來套用,做出來的成果如下圖,差異在於色彩的準確度上,使用畫線的方式來製作的色盤因為計算出來的hsl數值存在著一些誤差,在函式的自行進位後有許多相鄰坐標的顏色其實是同一色,所以看起來漸層模糊比較嚴重,而使用轉換公式再轉回rgb後,色彩的數值範圍變大,因此重覆的色彩數值減少,色盤看起來的顏色就比較飽滿一些。

色盤差異

後面有時間會再繼續研究一些比較實務的操作,象是圖表的製作或是小遊戲的製作。