> ## Documentation Index
> Fetch the complete documentation index at: https://extension.js.org/llms.txt
> Use this file to discover all available pages before exploring further.

# 在擴充功能中延遲載入大型函式庫

> 讓 Manifest V3 service worker 保持精簡。了解動態 import 在擴充功能中哪裡可用、哪裡不可用，以及按需載入大型函式庫的各種模式。

Manifest V3 的 service worker 經常會冷啟動：瀏覽器會在閒置約 30 秒後將它終止，並在下一個事件發生時重新啟動。每一 KB 你在 worker 最上層 import 進來的程式，都會在每次喚醒時被重新解析一次。如果你把打包好的 parser、wasm 執行階段或 AI SDK 放在 worker 進入點，那每一次 alarm、訊息與點擊都得付出這些成本。

## 動態 `import()` 可以在哪些地方使用

在打包工具介入之前，平台本身的規則如下：

| Context                   | 執行階段的動態 `import()` |
| ------------------------- | ------------------ |
| Service worker（背景）        | 否，規範不允許            |
| 擴充功能頁面（popup、選項、新分頁、側邊面板） | 是                  |
| Offscreen documents       | 是                  |
| Content scripts           | 是，但需要多一個步驟         |

service worker 上的限制最常讓人意外：在任何瀏覽器中，平台層面都不支援在 service worker 裡使用動態 `import()`。在 worker 最上層使用靜態 `import` 語句沒問題（Extension.js 會將它們打包），但你無法把一個 chunk 的載入延後到某個事件發生時才進行。

## 模式 1：依介面切分，而不是依 chunk 切分

service worker 的職責是協調，而不是運算。請讓它的靜態 import 僅止於黏合性程式（路由訊息、註冊監聽器），任何吃資源的工作都搬到能夠延遲載入的介面去：

* 跟 UI 相關的工作應該放在需要它的那個頁面。一個會格式化程式碼的 popup，就把 formatter import 在 popup 裡，而不是在 worker 裡。
* 只在背景發生的吃資源工作（解析、編碼、推論），應該放到[offscreen document](/docs/implementation-guide/offscreen-documents) — 按需建立、結束後關閉。worker 就保持為一個輕薄的訊息路由器。

```ts background.ts theme={null}
chrome.runtime.onMessage.addListener((message, _sender, sendResponse) => {
  if (message.type === "parse-feed") {
    ensureOffscreen()
      .then(() =>
        chrome.runtime.sendMessage({ target: "offscreen", ...message }),
      )
      .then(sendResponse);
    return true;
  }
});
```

接著 offscreen 頁面就可以在第一次被要求時才 `import()` 那個大型函式庫，這樣成本只會在每個 document 的生命週期內付一次，而不是每次 worker 喚醒都付一次。

## 模式 2：在擴充功能頁面中延遲 import

在任何擴充功能頁面裡，一般的動態 import 都可以正常運作，打包工具也會自動把 chunk 切分出來：

```ts popup.ts theme={null}
button.addEventListener("click", async () => {
  const { highlight } = await import("./heavy/highlighter");
  output.innerHTML = highlight(input.value);
});
```

這裡沒有任何擴充功能專屬的細節：chunk 會被輸出到你的 build 結果中，從擴充功能自己的 origin 載入。

## 模式 3：在 content scripts 中延遲 import

Content scripts 是在頁面的環境中執行，因此它們延遲載入的 chunk 必須能被那個頁面抓取。需要兩個步驟：

1. 透過 `web_accessible_resources` 公開這些 chunk 的路徑。
2. 透過 `chrome.runtime.getURL` 來 import，讓 URL 解析到你的擴充功能 origin：

```ts content.ts theme={null}
async function loadAnalyzer() {
  const src = chrome.runtime.getURL("content_scripts/analyzer.js");
  return import(src);
}
```

對應的 manifest 區塊請參見 [web\_accessible\_resources](/docs/implementation-guide/web-accessible-resources)。如果沒設定，import 會因為網路錯誤而失敗，因為宿主頁面無法抓取那些沒有被明確公開的擴充功能檔案。

## 哪些東西絕對不要放進 worker

* 任何跟 DOM 有關的東西（`DOMParser`、canvas、audio）：worker 完全沒有 DOM，請改用 offscreen document。
* 數 MB 大的 wasm：在 offscreen document 或[額外頁面](/docs/features/special-folders)中實體化它，並把結果快取到 `chrome.storage`，這樣重啟時成本才會低。
* 一次性的工具（匯入、遷移、匯出）：放在 `pages/` 底下的專屬頁面，可以讓它遠離每一條啟動路徑。

## 延伸閱讀

* [Background scripts](/docs/implementation-guide/background)
* [Offscreen documents](/docs/implementation-guide/offscreen-documents)
* [web\_accessible\_resources](/docs/implementation-guide/web-accessible-resources)
* [效能手冊](/docs/workflows/performance-playbook)
