LifeCycle of Browser
为什么页面会需要生命周期?
从浏览器架构中,我们知道了当打开一个Tab标签(页面)时,浏览器会为其创建多个进程,同时也就分配了进程占用的内存。但是随着大量网络应用的的运行,设备的关键资源,比如内存、CPU、电池等都会很容易超额订阅,也就是资源占用过多,得不到释放,最坏的情况就会导致整个应用奔溃。
因此,应用的生命周期是管理资源的关键方式。
从上图中可以看出,包含了web页面生命周期的状态以及事件
生命周期状态 state
生命周期的状态包含了Active
、Passive
、Hidden
、Frozen
、Terminated
和Discarded
Active
如果页面可见且具有输入焦点,则该页面处于活动状态。可能的先前状态: Passive
(通过焦点_focus
事件);可能的下一个状态: Passive
(通过blur
_事件)
Passive
如果页面可见且没有输入焦点,则该页面处于被动状态。
可能的先前状态:
Active
(通过blur
事件)hidden(
通过_visibilitychange
_事件);
可能的下一个状态:
Active
(通过_focus
_事件)- 隐藏(通过_
visibilitychange
_事件)
Hidden
如果页面不可见且未被冻结,则该页面处于隐藏状态。
可能的先前状态: Passive
(通过_visibilitychange
_事件);
可能的下一个状态:
Passive
(通过_visibilitychange
_事件)Frozen
(通过freeze
事件)Terminated
(通过页面pagehide
事件)
Frozen
在冻结状态下,浏览器将可冻结任务的执行暂停在页面的任务队列中,直到页面被解冻。这意味着诸如 JavaScript timer 和 fetch callbacks 之类的代码不会运行。已经运行的任务可以完成(最重要的是冻结回调) ,但是它们可以做的事情和可以运行的时间可能受到限制。
浏览器冻结页面是为了保持 CPU/电池/数据的使用; 它们也是为了实现更快的后退/前进导航(避免重新加载整个页面)。
可能的先前状态: hidden
(通过freeze
事件);
可能的下一个状态:
Active
(通过resume
事件,然后pageshow
事件)Passive
(通过resume
事件,然后pageshow
事件)hidden
(通过resume
事件)
Terminated
一旦页面开始被浏览器从内存中卸载和清除,它就处于终止状态。在此状态下不能启动任何新任务,如果运行时间过长,则可能会终止正在进行的任务。
可能的先前状态: hidden
(通过页面pagehide
事件)
接下来可能的状态是: 无
Discarded
当页面被浏览器卸载以节省资源时,它处于被丢弃的状态。任何任务、事件回调或任何类型的 JavaScript 都不能在这种状态下运行,因为丢弃通常是在资源约束下发生的,在这种情况下不可能启动新的进程。
在被丢弃的状态下,标签本身(包括标签标题和图标)通常对用户是可见的,即使页面已经消失。
可能的先前状态: Frozen
(没有事件触发)
接下来可能的状态是: 无
生命周期事件 events
浏览器分派了大量的事件,但是只有一小部分事件表明页面生命周期状态可能发生了变化。与生命周期相关的事件有focus
、blur
、visibilitychange
、freeze
、resume
、pageshow
、pagehide
、beforeunload
、unload
focus DOM 元素已经获得了焦点。
Note
一个 focus
事件并不一定意味着状态的改变。只有当页面以前没有输入焦点时,它才会发出状态更改的信号
blur DOM 元素失去了焦点。
Note
A blur
事件并不一定意味着状态的改变。如果页面不再具有输入焦点(即页面不只是将焦点从一个元素切换到另一个元素) ,那么它只会发出状态更改的信号
文档的 visibilityState 值已更改。当用户导航到一个新页面,切换标签页,关闭标签页,最小化或关闭浏览器,或者切换移动操作系统上的应用程序时,就会发生这种情况。
freeze
页面刚刚被冻结。页面任务队列中的任何可冻结任务都不会被启动。
resume
浏览器恢复了一个冻结的页面。
pageshow
正在遍历一个会话历史记录条目。这可能是一个全新的页面加载或从缓存取得的页面。如果页面是从缓存获取的,则事件的持久化属性为 true,否则为 false。
pagehide
正在从中遍历会话历史记录条目。如果用户正在导航到另一个页面,并且浏览器能够将当前页面添加到后退缓存中,以便稍后重用,则事件的持久化属性为 true。如果为 true,页面将进入冻结状态,否则将进入终止状态。
beforeunload
即将卸载窗口、文档及其资源。文档仍然可见,此时事件仍然可以取消。
Note
一个 beforeunload
事件应该只用于提醒用户未保存的更改。一旦保存了这些更改,就应该删除该事件。不应该无条件地将它添加到页面中,因为这样做在某些情况下会损害性能。参见legacy APIs section 遗留 api 部分 了解详情。
unload
正在卸载页面。
Note
一个 unload
事件从来不被推荐,因为它不可靠,在某些情况下可能会损害性能。参见legacy APIs section 遗留 api 部分 了解详情。