事件页面Event Pages
Apps和扩展最常用的需求就是一个生命周期长的脚本来管理任务或者状态。事件页就是干这个的。Event pages仅仅在被需要的时候加载,当它处于不活跃状态时,就会被销毁来释放内存和其他系统资源。Event pages在Chrome22提供稳定版本,它有着显著的性能优越性,尤其体现在低电量设备上。请在开发新程序和开始 迁移已存在的background页面 时优先选择Event pages来维持背景页。
Manifest
在扩展的manifest中注册
{
"name": "My extension",
...
"background":
{ "scripts": ["eventPage.js"],
"persistent": false
},
...
}
注意,没有“persistent”键就是常规的背景页。Persistence(是否一直存在)就是event page和background page的区别。
生命周期Lifetime
Event page 是在需要的时候加载,再次闲置的时候卸载(销毁)。下面是一些触发event page加载的事件:
- App或者看展第一次安装或者更新到新版本(为了注册事件register for events)
- Event page会一直监听事件,事件会被逐一分配。
- Content script或者扩展发送消息sends a message.
- 扩展中的其它视图(比如popup)调用runtime.getBackgroundPage
.
一旦处于加载状态,event page在活跃时就会一直处于运行状态(比如调用extention API或者发起网络请求)。另外,event page将不会卸载(销毁)除非所有可视试图(比如popup窗口)被关闭并且所有消息端口也关闭。注意,如果event page已经加载,打开一个视图不会再次触发加载,只会防止它被关闭(引用计数+1)。
确保你的event page在事件处理完之后马上关闭。你可以通过打开Chrome的任务管理器来查看事件的生命周期。在扩展出现在进程表上时就可以看到事件是什么时候加载和卸载了。
一旦event page被闲置一小会儿(几秒), runtime.onSuspendCanceled 事件就会被发送。
Event page在被强制卸载之前会有几秒的时间来处理这个事件。一般情况下,如果在这期间某个时间被触发,那么Event page就会被加载,挂起操作取消,runtime.onSuspendCanceled被发送。
事件迁移 Event registration
Chrome会一直追踪被添加到监听的App的事件或者扩展。当发送这样的事件的时候,event page就会被加载。 相反的, 如果app或者扩展通过removeListener
取消某一事件的所有监听器, Chrome将不再为这个事件加载它的event page。
因为监听器自身仅存在于event page的环境中,那就必须在每次event page加载的时候使用addListener
,仅在 runtime.onInstalled中这样做,并且此时它自身不足够实现。
事件迁移实例Google Mail Checker
Background page转换 Event page
按照这个列表来转换扩展的background page成event page
- 在manifest文件中添加
"persistent": false
- 如果扩展中使用了
window.setTimeout()
或者window.setInterval()
, 用alarms API替代.
基于DOM的计时器在页面被关闭的时候就会失效。 - 同样的,如果页面关闭,其它异步HTML5 APIs 像同志和地理位置将不会完成。取而代之,使用APIs,比如 notifications.
- 如果你的扩展使用了extension.getBackgroundPage, 请替换成runtime.getBackgroundPage. 新方法是异步的,必要时可以在先打开event page然后获得返回值。
使用event page最好的实践
记住这些技巧可以避免小错误。
-
每次加载的时候都要注册所有扩展需要用到的事件。Event page将在版本更新的时候加载一次。之后就只会用你注册的事件发送通知。通常这也意味着你的事件监听代码需要在event page代码结构的最顶层,否则在event page重载的时候它们可能会失效。
-
如果在扩展安装或者更新的时候需要做一些初始化,监听runtime.onInstalled事件。这是注册 declarativeWebRequest 最好的地方,contextMenu入口, 以及其他一次性初始化。
-
如果需要在内存中获取浏览器会话期间的运行时状态,使用 storage API 或者 IndexedDB。因为event page不会持续存在,你就不能再依靠全局变量来读取运行时状态。
-
使用event filters 来限制事件的通知. 比如,如果你在监听 tabs.onUpdated
事件, 请尝试使用带过滤器的 webNavigation.onCompleted
事件来替换(tabs API 不支持过滤器). 这样,你的event page就只会在你感兴趣的事件上加载。. -
如果你需要在页面关闭之前做倒数第二步的清理,请监听 runtime.onSuspend事件。
然而,我们建议使用持续性的。这样的话即使扩展崩溃的情况下没有收到onSuspend
事件也不会丢失数据。
请确认是否关闭了不常用的信息端口。Event page将不会关闭直到所有的端口都关闭。 -
如果你正在使用 message passing, be sure to close unused message ports. The event page will not shut down until all message ports are closed.
-
如果你正在使用context menus API, 给contextMenus.create传递字符串ID
, 然后使用contextMenus.onClicked
回掉代替contextMenus.create的onclick
参数。
. -
记得测试event page是否在闲置了几秒就会发生的加载和卸载时正常工作。通常错误包括在加载时包含不必要的工作(本应仅在扩展安装的时候完成的任务); 在加载时设置闹钟 (这会重置所有值钱的闹钟); 后者没有在加载的时候添加监听器.
以上》内容在CC-By 3.0 license有效
网友评论