最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 页面生命周期 API:每一个前端开发者都应该知道的浏览器 API

    正文概述 掘金(SamChord)   2020-12-16   734

    页面生命周期 API:每一个前端开发者都应该知道的浏览器 API

    页面生命周期 API:每一个前端开发者都应该知道的浏览器 API

    作为用户,我们在浏览网页时总是喜欢同时开启多个页面。因此,打开多个浏览器标签页是很常见的,因为这有助于我们并行地完成任务。但同时,这些标签页每一个都会消耗系统资源,如内存和 CPU。

    由于不可能限制用户打开新标签页,也不能放任不管新标签页。所以浏览器在标签页非激活态时采取了一些措施来重新分配资源。

    那么你可能会有疑问,既然浏览器已经处理好了,我们为什么还要担心这个问题呢?

    浏览器并没有完全处理好所有事情。此外,这些浏览器的干预措施会直接影响 JavaScript 的执行。好消息是,几乎所有现代浏览器都通过页面生命周期 API 把这些干预作为事件暴露出来了。

    页面生命周期 API

    顾名思义,页面生命周期 API 向 JavaScript 暴露了网页生命周期的钩子。然而,这不是一个全新的概念。页面可见性 API(Page Visibility API) 已经存在一段时间了,为 JavaScript 提供了一些页面可见性事件。

    然而,如果你恰好需要在这两者之间作出抉择,就需要考虑一下页面可见性 API 的一些限制。

    • 它只提供了网页显示和隐藏的状态
    • 它不能捕获被操作系统抛弃的页面(安卓、IOS 和最新的 Windows 系统可以终止后台进程以保存系统资源)

    让我们看一下通过页面生命周期 API 暴露的页面生命周期状态。

    页面生命周期 API 状态

    API 中介绍的状态有 6 种,其中,有两个状态和我们开发息息相关。

    • 冻结 —— CPU 暂停的生命周期状态(隐藏的页面会被冻结以节约资源)

    如果一个网页被隐藏了很久,并且用户没有关闭这个页面,浏览器将冻结它并把这个页面移动到这个状态里。然而,运行的任务会一直存在直到完成。但定时器、回调函数的执行和 DOM 操作将被停止以释放 CPU。

    页面生命周期 API:每一个前端开发者都应该知道的浏览器 API

    • 废弃 —— 冻结的窗口会被移到 Discarded 状态,以节省资源。

    假想一个网页长时间处于冻结态。这种情况下,浏览器将自动卸载页面让它进入废弃状态,以释放部分内存。并且如果用户重新访问废弃页面,浏览器将重新加载页面并回到激活状态。

    除了上述两种状态,API 中引入的其他四种状态为:

    • 激活 —— 页面可见并有输入焦点
    • 被动 —— 页面可见但没有输入焦点
    • 隐藏 —— 页面不可见(也不是冻结态)
    • 终止 —— 页面已卸载并且已从内存中清除

    你可以通过看下图找到生命周期状态和过渡的详细情况。

    页面生命周期 API:每一个前端开发者都应该知道的浏览器 API

    如何应对生命周期状态

    现在我们明白了页面生命周期 API,让我们看看咱们该如何应对每个事件。

    • 激活态 —— 由于用户在页面上是完全活跃的,所以你的网页应该完全响应用户的输入。任何 UI 阻塞任务都应该去掉优先级,比如同步和阻塞网络请求。
    • 被动态 —— 即便用户在这个阶段不和页面发生交互,他们仍然可以看到页面。因此你的网页应当流畅地运行所有 UI 更新和动画效果。
    • 隐藏态 —— 隐藏状态应视为用户在网页上的会话结束。此时可以将未保存的应用状态持久化,并停止任何用户不需要在后台运行的 UI 更新或任务。
    • 冻结态 —— 任何可能影响其他标签的定时器和连接都应在此阶段终止。例如,你应该关闭所有打开的 IndexedDB 连接,任何打开的 Web Socket 连接,释放任何被持有的 Web 锁,等等。
    • 终止态 —— 由于会话结束逻辑是在隐藏状态下处理的,所以(该阶段)一般不需要操作。
    • 废弃态 —— 这种状态是应用程序无法观测到的。因此,任何可能丢弃的准备工作都应该在隐藏或冻结状态下进行。然而,你可以在页面加载时通过检查 document.wasDiscarded 对页面的任何恢复做出响应。

    好的,现在我们知道在每个状态要做什么了,让我们看看如何在我们的应用程序中捕获每个状态。

    如何在你的代码中捕获生命周期状态

    你可以使用下面的 JavaScript 函数来确定一个给定页面的激活、被动和隐藏状态。

    const getState = () => {
      if (document.visibilityState === 'hidden') {
        return 'hidden';
      }
      if (document.hasFocus()) {
        return 'active';
      }
      return 'passive';
    };
    

    随着 Chrome 68 的发布,开发者可以通过监听 document 对象上的 freezeresume 事件来观察隐藏标签何时被冻结和解冻。

    document.addEventListener('freeze', (event) => {
      // 页面现在是冻结的
    });
    
    document.addEventListener('resume', (event) => {
      // 页面被解冻
    });
    

    要确定一个页面在隐藏标签页中是否被丢弃,可以使用以下代码。

    if (document.wasDiscarded) {
    // 页面之前在隐藏标签页中被浏览器丢弃
    } 
    

    上面提到的 wasDiscarded 属性可以在页面加载时被观察到。

    浏览器兼容性

    一些老的浏览器不具备检测何时网页被冻结或废弃的能力。然而,随着 Chome 68 的发布,预测页面下一个状态的能力也被加了进来。

    已知的兼容性问题

    • 一些浏览器在切换标签时不触发 blur 事件,这样可以避免页面进入到被动态。
    • 老版本的 IE(10 以下)没有实现 visibilityChange 事件。
    • 当关闭标签页时,Safari 浏览器不会一定确保能触发 pagehidevisibilitychange 事件。

    为了解决跨浏览器不兼容性问题,Google 已经开发了一个名叫 Pagelifecycle.js 的库,为以下浏览器做补充使用。

    页面生命周期 API:每一个前端开发者都应该知道的浏览器 API

    总结

    当用户没有主动参与时,网页不应该消耗过多的资源。此外你的应用程序还应该了解系统所执行的管理任务。页面生命周期 API 介绍了一种简单的方式来让你的应用程序知道这些事件。


    虽然它更多的是和高级用例相关,但我们可以通过了解它的功能来开发高效的网络应用。据此,我们可以为终端用户提供更好的体验。



    起源地下载网 » 页面生命周期 API:每一个前端开发者都应该知道的浏览器 API

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元