⽹页的6⼤⽣命周期
这⾥仅作学习记录,原⽂链接为阮⽼师的⽹站教程:
Page Lifecycle API 教程
Android、iOS 和最新的 Windows 系统可以随时⾃主地停⽌后台进程,及时释放系统资源。也就是说,⽹页可能随时被系统丢弃掉。Page Visibility API 只在⽹页对⽤户不可见时触发,⾄于⽹页会不会被系统丢弃掉,它就⽆能为⼒了。
为了解决这个问题,W3C 新制定了⼀个 Page Lifecycle API,统⼀了⽹页从诞⽣到卸载的⾏为模式,并且定义了新的事件,允许开发者响应⽹页状态的各种转换。
有了这个 API,开发者就可以预测⽹页下⼀步的状态,从⽽进⾏各种针对性的处理。Chrome 68 ⽀持这个 API,对于⽼式浏览器可以使⽤⾕歌开发的兼容库 PageLifecycle.js。
对于JS的⽣命周期请查看 JS的页⾯⽣命周期事件
⼀、⽣命周期阶段
⽹页的⽣命周期分成六个阶段,每个时刻只可能处于其中⼀个阶段。
image
(1)Active 阶段
如果还未进⼊Active前对应的是JS的DOMContentLoaded。adyState可以获取loading、interactive、interactive状态。
在 Active 阶段,⽹页处于可见状态,且拥有输⼊焦点。对应的是JS的load
(2)Passive 阶段
在 Passive 阶段,⽹页可见,但没有输⼊焦点,⽆法接受输⼊。UI 更新(⽐如动画)仍然在执⾏。该阶段只可能发⽣在桌⾯同时有多个窗⼝的情况。
(3)Hidden 阶段
在 Hidden 阶段,⽤户的桌⾯被其他窗⼝占据,⽹页不可见,但尚未冻结。UI 更新不再执⾏。
(4)Terminated 阶段
在 Terminated 阶段,由于⽤户主动关闭窗⼝,或者在同⼀个窗⼝前往其他页⾯,导致当前页⾯开始被浏览器卸载并从内存中清除。注意,这个阶段总是在 Hidden 阶段之后发⽣,也就是说,⽤户主动离开当前页⾯,总是先进⼊ Hidden 阶段,再进⼊ Terminated 阶段。中间依次有JS的beforeunload和window.unload
这个阶段会导致⽹页卸载,任何新任务都不会在这个阶段启动,并且如果运⾏时间太长,正在进⾏的任务可能会被终⽌。
(5)Frozen 阶段
如果⽹页处于 Hidden 阶段的时间过久,⽤户⼜不关闭⽹页,浏览器就有可能冻结⽹页,使其进⼊ Frozen 阶段。不过,也有可能,处于可见状态的页⾯长时间没有操作,也会进⼊ Frozen 阶段。
这个阶段的特征是,⽹页不会再被分配 CPU 计算资源。定时器、回调函数、⽹络请求、DOM 操作都不会执⾏,不过正在运⾏的任务会执⾏完。浏览器可能会允许 Frozen 阶段的页⾯,周期性复苏⼀⼩段时间,短暂变回 Hidden 状态,允许⼀⼩部分任务执⾏。
(6)Discarded 阶段
如果⽹页长时间处于 Frozen 阶段,⽤户⼜不唤醒页⾯,那么就会进⼊ Discarded 阶段,即浏览器⾃动卸载⽹页,清除该⽹页的内存占⽤。不过,Passive 阶段的⽹页如果长时间没有互动,也可能直接进⼊ Discarded 阶段。
这⼀般是在⽤户没有介⼊的情况下,由系统强制执⾏。任何类型的新任务或 JavaScript 代码,都不能在此阶段执⾏,因为这时通常处在资源限制的状况下。
⽹页被浏览器⾃动 Discarded 以后,它的 Tab 窗⼝还是在的。如果⽤户重新访问这个 Tab 页,浏览器将会重新向服务器发出请求,再⼀次重新加载⽹页,回到 Active 阶段。
⼆、常见场景
以下是⼏个常见场景的⽹页⽣命周期变化。
(1)⽤户打开⽹页后,⼜切换到其他 App,但只过了⼀会⼜回到⽹页。
⽹页由 Active 变成 Hidden,⼜变回 Active。
(2)⽤户打开⽹页后,⼜切换到其他 App,并且长时候使⽤后者,导致系统⾃动丢弃⽹页。
网页历史记录恢复⽹页由 Active 变成 Hidden,再变成 Frozen,最后 Discarded。
(3)⽤户打开⽹页后,⼜切换到其他 App,然后从任务管理器⾥⾯将浏览器进程清除。
⽹页由 Active 变成 Hidden,然后 Terminated。
(4)系统丢弃了某个 Tab ⾥⾯的页⾯后,⽤户重新打开这个 Tab。
⽹页由 Discarded 变成 Active。
三、事件
⽣命周期的各个阶段都有⾃⼰的事件,以供开发者指定监听函数。这些事件⾥⾯,只有两个是新定义的(freeze事件和resume事件),其它都是现有的。
注意,⽹页的⽣命周期事件是在所有帧(frame)触发,不管是底层的帧,还是内嵌的帧。也就是说,内嵌的<iframe>⽹页跟顶层⽹页⼀样,都会同时监听到下⾯的事件。
3.1 f ocus 事件
focus事件在页⾯获得输⼊焦点时触发,⽐如⽹页从 Passive 阶段变为 Active 阶段。