迁移到事件驱动型后台脚本

实现非永久性后台脚本可大幅降低扩展程序的资源开销。大多数扩展程序功能都可以通过基于事件的后台脚本来支持。只有在极少数情况下,扩展程序才应具有持久的后台,因为它们会持续消耗系统资源,并可能会给低功耗设备造成压力。

通过将永久性后台脚本迁移到基于事件的非永久性模型,提升扩展程序的性能。默认情况下,"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
})

记录存储空间中的状态更改

使用存储 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()
  })
});