The Will Will Web

記載著 Will 在網路世界的學習心得與技術分享

前端效能調校:使用 Partytown 將笨重的 JavaScript 放到 Web Workers 執行

前端效能調校的技法多如牛毛,但最明顯的效能殺手不外乎是 JavaScript 佔用 Main Thread 而導致頁面無法回應的狀況了。最近研究 Partytown 這個函式庫,他用了一個非常巧妙的技巧,把部分 JS 自動切換到 Web Workers 背景執行。這篇文章我就來分享如何將 Partytown 安裝到任意網站中。

Partytown - Run Third-Party Scripts From A Web Worker

如何安裝 Partytown 到任意網站

以下是安裝步驟:

  1. 透過 Partytown CLI 下載 Partytown 函式庫

    以下命令會在當前目錄建立一個 ~partytown 資料夾(建議統一用這個名稱):

    npx "@builder.io/partytown" copylib ~partytown
    
  2. ~partytown 資料夾上傳到網站根目錄

    如果是 ASP.NET Core 的話,可以上傳到 wwwroot 目錄下,或是在 ASP.NET Core 專案根目錄輸入以下命令:

    npx "@builder.io/partytown" copylib "wwwroot\~partytown"
    

    如果是 Node.js 的話,可以上傳到 public 目錄下,或是在 ASP.NET Core 專案根目錄輸入以下命令:

    npx "@builder.io/partytown" copylib "public/~partytown"
    

    你也可以設定好 package.json 加入到建置流程中:

    npm install "@builder.io/partytown"
    
    {
      "scripts": {
        "build": "npm run partytown && ng build",
        "partytown": "partytown copylib public/~partytown"
      }
    }
    

    總之,上傳到網站根目錄就對了!(詳見 Copy Library Files 有更完整的說明)

  3. 調整網頁中的 <script> 標籤語法

    請將以下:

    <script>...</script>
    

    全部修改為:

    <script type="text/partytown">...</script>
    

    就大功告成!

使用的注意事項

雖然 Partytown 函式庫的初衷非常理想,就是管理第三方 JS 函式庫(third-party scripts),徹底降低 JS 佔用 Main Thread 的狀況。但實際上還是有不少 JS 檔案在透過 Partytown 載入到 Web Workers 執行後就掛掉了,所以實際上 Partytown 並不適用於所有 JS 執行,因此不太建議把網站上所有 JS 都改用 Partytown 來載入。

除此之外,目前 Partytown 因為有用到 Atomics API 的關係,它的相容性確實有些限制,有些太舊的手機版本是沒有支援的!詳見 JavaScript built-in: Atomics | Can I use 說明。

最後要提醒大家的地方,就是使用 Partytown 的 Trade-Offs (權衡)。因為這個世界沒有銀子彈,有一好就沒兩好,使用 Partytown 不見得適用所有的網頁開發情境。以下是 Partytown 官方認為不適用的地方:

  1. 大量的 DOM 操作會被節流(Throttled DOM Operations)

    由於在 Web Workers 無法直接存取 DOM,所以 Partytown 會透過 onmessage 事件傳給 Main Thread 來處理,所以 DOM 處理的速度反而會變慢!

  2. 只要是 UI 特別吃重的 JS 函式庫,處理大量 DOM 操作,都不太適合用 Partytown 來管理

    如果執行實際效果不理想,其實就這個 JS 不要用 Partytown 即可!

  3. 若第三方函式庫在載入時沒有設定 CORS Headers 的話,透過 Partytown 是無法載入的

    必須透過 Proxying Requests相同來源(Same-origin)載入!

  4. 事件處理只要用到 event.preventDefault() 就會失效

    透過 Web Workers 執行 event callback 會導致 event.preventDefault() 的行為失效!

  5. 若透過 Partytown 管理的 JS 動態建立 iframe 的話,document.cookie, localStoragesessionStorage 都會讀不到!

    基本上程式不會報錯,但就是沒效果,所以使用上要注意!

  6. 透過 setInterval() 不斷的對 document 進行 DOM 操作

    這也會失去使用 Partytown 的價值,因為頻繁的 DOM 操作反而會讓 Web Workers 過於忙碌!

目前確定很適合用 Partytown 來管理的第三方函式庫,從官網是有整理出來的,大家可以多多利用,照著官網設定即可:

相關連結

留言評論