如何使用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 相关文章推荐
jQuery一步一步实现跨浏览器的可编辑表格,支持IE、Firefox、Safari、Chrome、Opera
Aug 28 Javascript
jQuery 幻灯片插件(带缩略图功能)
Jan 24 Javascript
js使用正则实现ReplaceAll全部替换的方法
Jul 18 Javascript
Jquery仿IGoogle实现可拖动窗口示例代码
Aug 22 Javascript
基于JavaScript代码实现微信扫一扫下载APP
Dec 30 Javascript
jquery 遍历数组 each 方法详解
May 25 Javascript
需灵活掌握的Bootstrap预定义排版类 你精通吗?
Jun 20 Javascript
js实现股票实时刷新数据案例
May 14 Javascript
Node.js v8.0.0正式发布!看看带来了哪些主要新特性
Jun 02 Javascript
深入理解js 中async 函数的含义和用法
May 13 Javascript
JavaScript实现简单的隐藏式侧边栏功能示例
Aug 31 Javascript
Vue实现浏览器打印功能的代码
Apr 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
一个用于mysql的数据库抽象层函数库
2006/10/09 PHP
Prototype使用指南之selector.js说明
2008/10/26 Javascript
解读JavaScript代码 var ie = !-[1,] 最短的IE判定代码
2011/05/28 Javascript
js调用webservice中的方法实现思路及代码
2013/02/25 Javascript
JS、CSS以及img对DOMContentLoaded事件的影响
2014/08/12 Javascript
JavaScript 学习笔记之操作符
2015/01/14 Javascript
分享网页检测摇一摇实例代码
2016/01/14 Javascript
JavaScript常用数组算法小结
2016/02/13 Javascript
15款最好的Bootstrap在线编辑器
2016/08/03 Javascript
jquery实现文本框的禁用和启用
2016/12/07 Javascript
详解jQuery中的DOM操作
2016/12/23 Javascript
vue新vue-cli3环境配置和模拟json数据的实例
2018/09/19 Javascript
写一个Vue Popup组件
2019/02/25 Javascript
[57:28]2018DOTA2亚洲邀请赛 4.6 淘汰赛 TNC vs Liquid 第一场
2018/04/10 DOTA
[53:44]DOTA2-DPC中国联赛 正赛 PSG.LGD vs Magma BO3 第一场 1月31日
2021/03/11 DOTA
python通过装饰器检查函数参数数据类型的方法
2015/03/13 Python
详解Python进程间通信之命名管道
2017/08/28 Python
python实现在遍历列表时,直接对dict元素增加字段的方法
2019/01/15 Python
python matplotlib imshow热图坐标替换/映射实例
2020/03/14 Python
解决python父线程关闭后子线程不关闭问题
2020/04/25 Python
python json.dumps() json.dump()的区别详解
2020/07/14 Python
华为C++笔试题
2014/08/05 面试题
自动化职业生涯规划书范文
2014/01/03 职场文书
违反课堂纪律检讨书
2014/01/19 职场文书
关于廉洁的广播稿
2014/01/30 职场文书
点菜员岗位职责范本
2014/02/14 职场文书
应聘编辑自荐信范文
2014/03/12 职场文书
公司运动会策划方案
2014/05/25 职场文书
临床专业自荐信
2014/06/22 职场文书
药店促销活动策划方案
2014/08/24 职场文书
迎国庆横幅标语
2014/10/08 职场文书
经典祝酒词大全
2015/08/12 职场文书
css3中transform属性实现的4种功能
2021/08/07 HTML / CSS
Nginx配置文件详解以及优化建议指南
2021/09/15 Servers
基于Python实现对比Exce的工具
2022/04/07 Python
golang使用map实现去除重复数组
2022/04/14 Golang