遷移至事件導向背景指令碼

實作非持續性背景指令碼可大幅降低擴充功能的資源成本。事件式背景指令碼可以支援大多數的擴充功能功能。只有在罕見情況下,擴充功能才應有永久背景,因為這類擴充功能會持續耗用系統資源,並可能在低階裝置上造成負擔。

將持續性背景指令碼遷移至事件導向的非持續性模型,藉此提升擴充功能效能。"persistent" 的預設值為 true。

將持久性指定為 false

在擴充功能的manifest檔案中找出 "background" 鍵,然後新增或更新 "persistent" 欄位,將其設為 false。

{
  "name": "My extension",
  ...
  "background": {
    "scripts": ["background.js"],
    "persistent": false
  },
  ...
}

同樣適用於依賴 HTML 檔案的背景指令碼。

{
  "name": "My extension",
  ...
  "background": {
    "page": "background.html",
    "persistent": false
  },
  ...
}

顯示事件監聽器

如果觸發重要事件,事件監聽器必須位於頂層才能啟用背景指令碼。註冊的事件監聽器可能需要改為同步模式。如以下所示,如果事件監聽器未同步註冊,則無法叫用。

chrome.storage.local.get('runtimeEvents', function (events) {
  for (let event of events)
    chrome.runtime[event].addListener(listener);
});

請改為將事件監聽器維持在頂層且未巢狀結構。

chrome.runtime.onStartup.addListener(function() {
  // run startup function
})

記錄儲存空間中的狀態變更

使用 storage API 設定及傳回狀態和值。使用 local.set 在本機更新。

  chrome.storage.local.set({ variable: variableInformation });

使用 local.get 擷取該變數的值。

chrome.storage.local.get(['variable'], function(result) {
  let awesomeVariable = result.variable;
  // Do something with awesomeVariable
});

將計時器轉換成鬧鐘

如果以 DOM 為基礎的計時器 (例如 window.setTimeout()window.setInterval()) 在事件網頁處於休眠狀態時觸發,則在非持久背景指令碼中不會執行。

let timeout = 1000 * 60 * 3;  // 3 minutes in milliseconds
window.setTimeout(function() {
  alert('Hello, world!');
}, timeout);

請改用 alarms API

chrome.alarms.create({delayInMinutes: 3.0})

然後新增事件監聽器。

chrome.alarms.onAlarm.addListener(function() {
  alert("Hello, world!")
});

更新背景指令碼函式的呼叫

如果使用 extension.getBackgroundPage 從背景頁面呼叫函式,請更新為 runtime.getBackgroundPage。較新的方法會在傳回非永久指令碼前啟用非永久指令碼。

function backgroundFunction() {
  alert('Background, reporting for duty!')
}
document.getElementById('target').addEventListener('click', function(){
  chrome.extension.getBackgroundPage().backgroundFunction();
});

如果背景指令碼處於停用狀態 (這是非持久性指令碼的預設狀態),這個方法就無法運作。較新的做法包含回呼函式,可確保背景指令碼已載入。

document.getElementById('target').addEventListener('click', function() {
  chrome.runtime.getBackgroundPage(function(backgroundPage){
    backgroundPage.backgroundFunction()
  })
});