如何使用JavaScript检测空闲的浏览器选项卡


Posted in Javascript onMay 28, 2020

在某些情况下,当用户与我们的最终产品或应用程序进行交互时,我们发现自己会执行许多密集的,占用大量CPU的任务。启动轮询器,建立WebSocket连接,甚至加载视频或图片等媒体,都有可能成为性能障碍,尤其是当这些任务在不需要的情况下消耗资源的时候。

在用户没有主动与界面交互的同时,从不必要的工作负载或网络请求中释放主线程是一个非常好的和有意义的实践。换一种方式,在大多数主机提供商都在引入基于配额的定价模式的行业中,减少网络请求也可以降低运行应用程序或服务的成本。

如何使用JavaScript检测空闲的浏览器选项卡

页面可见性(Page Visibility) API

所有现代的网页浏览器都加入了页面可见性API,它允许我们检测浏览器的标签页何时被隐藏,此外,我们还可以注册一个事件监听器,以检测可见性变化时的信号。

document.visibilityState

当页面处于前台时,document.visibilityState 可能是 visible ,最小化窗口的“标签”或隐藏。

我们可以通过以下方式直接访问 document.visibilityState:

console.log(document.visibilityState); 
// => 它可以是“visible”或“hidden”

visibilitychange Event

我们还可以使用事件侦听器轻松检测可见性属性中的更改。

const onVisibilityChange = () => { 
 if (document.visibilityState === 'hidden') { 
  console.log('> 这个窗口是隐藏的.'); 
 } else { 
  console.log('> 这个窗口是可见的.'); 
 } 
}; 
document.addEventListener('visibilitychange', onVisibilityChange, false);

轮询示例

考虑一种情况,在这种情况下,我们正在轮询API以获取更新,并且希望避免对空闲用户进行不必要的调用。一个简化的示例如下所示:

const poll = () => { 
 const interval = 1500; 
 let _poller = null; 
 const repeat = () => { 
  console.log(`~ Polling: ${Date.now()}.`); 
 }; 
 
 return { 
  start: () => { 
   _poller = setInterval(repeat, interval); 
  }, 
  stop: () => { 
   console.log('~ Poller stopped.'); 
   clearInterval(_poller); 
  } 
 }; 
}; 
 
const poller = poll(); 
poller.start(); 
 
const onVisibilityChange = () => { 
 if (document.visibilityState === 'hidden') { 
  poller.stop(); 
 } else { 
  poller.start(); 
 } 
}; 
 
document.addEventListener('visibilitychange', onVisibilityChange, false);

在后台异步加载

但有时我们可以通过反其道而行之,加速用户的终端体验。我们可以异步加载外部依赖或资产,而不是取消所有的作业和请求。这样,当用户回来时,他们的最终体验将更加“充实”并且丰富。

如何使用JavaScript检测空闲的浏览器选项卡

/ Webpack /

使用ES2015动态导入建议和适当的Webpack配置清单,我们可以轻松地在后台加载额外的模块或资产。

let loaded = false; 
const onVisibilityChange = () => { 
 if (document.visibilityState === 'hidden') { 
  // Aggresively preload external assets ans scripts 
  if (loaded) { 
   return; 
  } 
  Promise.all([ 
   import('./async.js'), 
   import('./another-async.js'), 
   import(/* webpackChunkName: "bar-module" */ 'modules/bar'), 
   import(/* webpackPrefetch: 0 */ 'assets/images/foo.jpg') 
  ]).then(() => { 
   loaded = true; 
  }); 
 } 
}; 
 
document.addEventListener('visibilitychange', onVisibilityChange, false);

/ Rollup /

Rollup还支持开箱即用的动态导入。

let loaded = false; 
const onVisibilityChange = () => { 
 if (document.visibilityState === 'hidden') { 
  // Aggresively preload external assets ans scripts 
  if (loaded) { 
   return; 
  } 
  Promise.all([ 
   import('./modules.js').then(({default: DefaultExport, NamedExport}) => { 
    // do something with modules. 
   }) 
  ]).then(() => { 
   loaded = true; 
  }); 
 } 
}; 
 
document.addEventListener('visibilitychange', onVisibilityChange, false);

/ 用Javascript预加载 /

除了使用捆绑器,我们还可以仅使用几行JavaScript来预加载静态资源(例如图像)。

let loaded = false; 
const preloadImgs = (...imgs) => { 
 const images = []; 
 imgs.map( 
  url => 
   new Promise((resolve, reject) => { 
    images[i] = new Image(); 
    images[i].src = url; 
    img.onload = () => resolve(); 
    img.onerror = () => reject(); 
   }) 
 ); 
}; 
const onVisibilityChange = () => { 
 if (document.visibilityState === 'hidden') { 
  // Aggresively preload external assets ans scripts 
  if (loaded) { 
   return; 
  } 
  Promise.all( 
   preloadImgs( 
    'https://example.com/foo.jpg', 
    'https://example.com/qux.jpg', 
    'https://example.com/bar.jpg' 
   ) 
  ) 
   .then(() => { 
    loaded = true; 
   }) 
   .catch(() => { 
    console.log('> Snap.'); 
   }); 
 } 
}; 
document.addEventListener('visibilitychange', onVisibilityChange, false);

微互动

最后,一种吸引用户注意力的巧妙方法是动态更改图标,只需使用几个像素就可以保持交互。

const onVisibilityChange = () => { 
 const favicon = document.querySelector('[rel="shortcut icon"]'); 
 if (document.visibilityState === 'hidden') { 
  favicon.href = '/come-back.png'; 
 } else { 
  favicon.href = '/example.png'; 
 } 
}; 
 
document.addEventListener('visibilitychange', onVisibilityChange, false);

总结

到此这篇关于如何使用JavaScript检测空闲的浏览器选项卡的文章就介绍到这了,更多相关js浏览器选项卡内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Javascript 相关文章推荐
javascript flash下fromCharCode和charCodeAt方法使用说明
Jan 12 Javascript
jQuery DOM操作小结与实例
Jan 07 Javascript
Javascript下IE与Firefox下的差异兼容写法总结
Jun 18 Javascript
JavaScript性能优化 创建文档碎片(document.createDocumentFragment)
Jul 13 Javascript
js switch case default 的用法示例介绍
Oct 23 Javascript
JS获取键盘上任意按键的值(实例代码)
Nov 12 Javascript
jquery.cookie.js使用指南
Jan 05 Javascript
js+div实现文字滚动和图片切换效果代码
Aug 27 Javascript
jQuery查找节点并获取节点属性的方法
Sep 09 Javascript
Vue+Jwt+SpringBoot+Ldap完成登录认证的示例代码
May 21 Javascript
Vue.use源码学习小结
Jun 20 Javascript
JavaScript前端面试组合函数
Jun 21 Javascript
js实现轮播图特效
May 28 #Javascript
JS写滑稽笑脸运动效果
May 28 #Javascript
Python版实现微信公众号扫码登陆
May 28 #Javascript
基于aotu.js实现微信自动添加通讯录中的联系人功能
May 28 #Javascript
原生js实现五子棋游戏
May 28 #Javascript
Vue微信公众号网页分享的示例代码
May 28 #Javascript
纯JS实现五子棋游戏
May 28 #Javascript
You might like
php 正则匹配函数体
2009/08/25 PHP
ThinkPHP分组下自定义标签库实例
2014/11/01 PHP
通过chrome浏览器控制台(Console)进行PHP Debug的方法
2016/10/19 PHP
JS 判断代码全收集
2009/04/28 Javascript
JavaScrip单线程引擎工作原理分析
2010/09/04 Javascript
如何使用Jquery获取Form表单中被选中的radio值
2013/08/09 Javascript
iframe窗口高度自适应的实现方法
2014/01/08 Javascript
JS实现倒计时和文字滚动的效果实例
2014/10/29 Javascript
快速掌握Node.js之Window下配置NodeJs环境
2016/03/21 NodeJs
jQuery实现手机版页面翻页效果的简单实例
2016/10/05 Javascript
jQuery Easyui加载表格出错时在表格中间显示自定义的提示内容
2016/12/08 Javascript
JavaScript限制在客户区可见范围的拖拽(解决scrollLeft和scrollTop的问题)(2)
2017/05/17 Javascript
JS+Ajax实现百度智能搜索框
2017/08/04 Javascript
使用 Vue cli 3.0 构建自定义组件库的方法
2019/04/30 Javascript
JavaScript命名空间模式实例详解
2019/06/20 Javascript
vue 解决addRoutes多次添加路由重复的操作
2020/08/04 Javascript
Python学习之asyncore模块用法实例教程
2014/09/29 Python
为Python程序添加图形化界面的教程
2015/04/29 Python
用python实现简单EXCEL数据统计的实例
2017/01/24 Python
flask中主动抛出异常及统一异常处理代码示例
2018/01/18 Python
对Tensorflow中权值和feature map的可视化详解
2018/06/14 Python
Windows 64位下python3安装nltk模块
2018/09/19 Python
不到40行代码用Python实现一个简单的推荐系统
2019/05/10 Python
Python安装与基本数据类型教程详解
2019/05/29 Python
详解python uiautomator2 watcher的使用方法
2019/09/09 Python
Jupyter notebook 启动闪退问题的解决
2020/04/13 Python
浅谈Python中的生成器和迭代器
2020/06/19 Python
阿拉伯时尚购物网站:Nisnass
2021/02/07 全球购物
泰国排名第一的家居用品中心:HomePro
2020/11/18 全球购物
以太网Ethernet IEEE802.3
2013/08/05 面试题
七夕活动策划方案
2014/08/16 职场文书
公民授权委托书范本
2014/09/17 职场文书
2014年群众路线教育实践活动整改措施
2014/09/24 职场文书
2015年度培训工作总结范文
2015/04/02 职场文书
MySQL配置主从服务器(一主多从)
2021/08/07 MySQL
TV动画《神废柴☆偶像》公布先导PV
2022/03/20 日漫