動態 import() 可以在哪些地方使用
在打包工具介入之前,平台本身的規則如下:
| Context | 執行階段的動態 import() |
|---|---|
| Service worker(背景) | 否,規範不允許 |
| 擴充功能頁面(popup、選項、新分頁、側邊面板) | 是 |
| Offscreen documents | 是 |
| Content scripts | 是,但需要多一個步驟 |
import()。在 worker 最上層使用靜態 import 語句沒問題(Extension.js 會將它們打包),但你無法把一個 chunk 的載入延後到某個事件發生時才進行。
模式 1:依介面切分,而不是依 chunk 切分
service worker 的職責是協調,而不是運算。請讓它的靜態 import 僅止於黏合性程式(路由訊息、註冊監聽器),任何吃資源的工作都搬到能夠延遲載入的介面去:- 跟 UI 相關的工作應該放在需要它的那個頁面。一個會格式化程式碼的 popup,就把 formatter import 在 popup 裡,而不是在 worker 裡。
- 只在背景發生的吃資源工作(解析、編碼、推論),應該放到offscreen document — 按需建立、結束後關閉。worker 就保持為一個輕薄的訊息路由器。
background.ts
import() 那個大型函式庫,這樣成本只會在每個 document 的生命週期內付一次,而不是每次 worker 喚醒都付一次。
模式 2:在擴充功能頁面中延遲 import
在任何擴充功能頁面裡,一般的動態 import 都可以正常運作,打包工具也會自動把 chunk 切分出來:popup.ts
模式 3:在 content scripts 中延遲 import
Content scripts 是在頁面的環境中執行,因此它們延遲載入的 chunk 必須能被那個頁面抓取。需要兩個步驟:- 透過
web_accessible_resources公開這些 chunk 的路徑。 - 透過
chrome.runtime.getURL來 import,讓 URL 解析到你的擴充功能 origin:
content.ts
哪些東西絕對不要放進 worker
- 任何跟 DOM 有關的東西(
DOMParser、canvas、audio):worker 完全沒有 DOM,請改用 offscreen document。 - 數 MB 大的 wasm:在 offscreen document 或額外頁面中實體化它,並把結果快取到
chrome.storage,這樣重啟時成本才會低。 - 一次性的工具(匯入、遷移、匯出):放在
pages/底下的專屬頁面,可以讓它遠離每一條啟動路徑。

