如何使用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字符串处理性能的代码
Dec 07 Javascript
jQuery 行背景颜色的交替显示(隔行变色)实现代码
Dec 13 Javascript
jquery keypress,keyup,onpropertychange键盘事件
Jun 25 Javascript
jQuery 绑定事件到动态创建的元素上的方法实例
Aug 18 Javascript
如何获取select下拉框的值(option没有及有value属性)
Nov 08 Javascript
jquery使用append(content)方法注意事项分享
Jan 06 Javascript
判断在css加载完毕后执行后续代码示例
Sep 03 Javascript
jquery.idTabs 选项卡使用示例代码
Sep 03 Javascript
Javascript中的几种继承方式对比分析
Mar 22 Javascript
基于ES6 Array.of的用法(实例讲解)
Sep 05 Javascript
vue项目tween方法实现返回顶部的示例代码
Mar 02 Javascript
谈谈JavaScript中的垃圾回收机制
Sep 17 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 cout<<的一点看法
2010/01/24 PHP
php集成开发环境详解
2019/09/24 PHP
javascript基础的动画教程,直观易懂
2007/01/10 Javascript
JQuery 风格的HTML文本转义
2009/07/01 Javascript
JavaScript的类型简单说明
2010/09/03 Javascript
javascript定义函数的方法
2010/12/06 Javascript
jQuery中调用WebService方法小结
2011/03/28 Javascript
jQuery1.6 使用方法二
2011/11/23 Javascript
jQuery lazyLoad图片延迟加载插件的优化改造方法分享
2013/08/13 Javascript
PHP配置文件php.ini中打开错误报告的设置方法
2015/01/09 PHP
jquery mobile开发常见问题分析
2016/01/21 Javascript
微信小程序多张图片上传功能
2017/06/07 Javascript
NodeJS父进程与子进程资源共享原理与实现方法
2018/03/16 NodeJs
vue父组件触发事件改变子组件的值的方法实例详解
2019/05/07 Javascript
小程序简单两栏瀑布流效果的实现
2019/12/18 Javascript
JS如何操作DOM基于表格动态展示数据
2020/10/15 Javascript
五句话帮你轻松搞定js原型链
2020/12/09 Javascript
[01:03:03]VP vs Mineski 2018国际邀请赛淘汰赛BO3 第一场 8.22
2018/08/23 DOTA
python daemon守护进程实现
2016/08/27 Python
Python编程实现二叉树及七种遍历方法详解
2017/06/02 Python
使用pandas将numpy中的数组数据保存到csv文件的方法
2018/06/14 Python
python opencv实现旋转矩形框裁减功能
2018/07/25 Python
pygame游戏之旅 添加游戏界面按键图形
2018/11/20 Python
python实现对图片进行旋转,放缩,裁剪的功能
2019/08/07 Python
python正则爬取某段子网站前20页段子(request库)过程解析
2019/08/10 Python
Python flask框架端口失效解决方案
2020/06/04 Python
Kathmandu澳洲户外商店:新西兰户外运动品牌
2017/11/12 全球购物
公务员的自我鉴定
2013/10/26 职场文书
临床医学系毕业生推荐信
2013/11/09 职场文书
2013的个人自我评价
2013/12/26 职场文书
2014国培学习感言
2014/03/05 职场文书
关于感恩的演讲稿500字
2014/08/26 职场文书
2014年妇女工作总结
2014/12/06 职场文书
庆祝教师节活动总结
2015/03/23 职场文书
陪护人员误工证明
2015/06/24 职场文书
2016大学生社会实践心得体会范文
2016/01/14 职场文书