昨天說了那個承包案子的首頁用了 GSAP 的 ScrollTrigger,今天就來說說我負責開發的頁面做了什麼吧~也是一個微鬼故事的節奏...
一開始原本的頁面設計是,畫面的背景會自動播放一個影片,中央則是讓一個玻璃材質的 glb 模型自己旋轉展示,左右兩邊各有一個按鈕可以切換展示中的模型,下方則有一個生化人講話的影片與字幕。但實作上卻遇到了困難,在瀏覽器中渲染模型時,模型的貼圖無法顯示,問了其他同事才知道,這個玻璃材質的貼圖太過複雜,導致只能在 Blender 中顯示,然而原本的設計師離職了無法協助修改,而業主也堅持這種 blink blink 的效果。
後來又添加了幾個需求,簡單來說就是:模型與背景的動畫播放幀數要一致,且如果在模型旋轉的第三幀切換模型,下一個模型必須從第四幀開始播放。於是高層決定將影片與 glb 檔全部捨棄,全部換成一張張的圖片,來一幀幀的播放。我聽到這個決定時,不禁冒起冷汗,開始按計算機:
一共有十個模型,每個模型轉一圈需要 16 秒,每秒 24 幀...模型動畫圖片一共就有 3840 張!!!!
還沒算背景圖片,也有 384 張...
「真的會有人這樣做網頁動畫嗎?」我不禁這樣想。
總之,我還是做了。沒記錯的話,為了避免一次載入過多圖片,我在動畫的圖片組中採用了動態載入的方式,並使用 useCallback 來避免播放動畫邏輯的重建,然而畫面還是有卡頓,有時甚至無法按下切換模型的按鈕...更別提手機燙得跟剛出爐的地瓜一樣...但業主還是不想做任何的妥協,甚至開始用 chatgpt 來提更多的需求,就是一個小孩子才做選擇,我全都要的感覺,而高層也沒有要擋需求的意思,只想著快點拿到尾款。
雖然當時我已經快要離職了,還是想解決這個問題,突然間,我想到某天早上閱讀到 Web Workers,似乎可以派上用場!!!!
一般來說,Javascript 是單一執行緒,如果在執行大量計算時,有可能會造成 UI 卡頓,因為所有的任務,包含畫面渲染、使用者事件處理、資料運算,都在同一條主執行緒(Main Thread)上執行。而 Web Workers 就是在主執行緒外再開一個執行緒,在背景中默默工作,就像是偷偷雇用來的乖乖地精(?值得注意的是,Workers 是一個獨立的執行環境,在背景默默工作,所以不能直接操作 DOM,和主執行緒透過 postMessage 和 onmessage 來傳遞資料,適合重計算、不依賴 DOM 的工作。
於是我將動畫的邏輯移至 Web Workers 運作後,畫面就順暢許多了,真感謝當時堅持每天閱讀的我自己XD
附上當時觀看的 Web Workers 的影片:JavaScript Web Workers Explained