如何使用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 相关文章推荐
asp.net+js 实现无刷新上传解析csv文件的代码
May 17 Javascript
改写一个简单的菜单 弹性大小
Dec 02 Javascript
利用javascript判断文件是否存在
Dec 31 Javascript
jQuery基础的工厂函数以及定时器的经典实例分析
May 20 Javascript
jquery.serialize() 函数语法及简单实例
Jul 08 Javascript
基于Vue.js实现数字拼图游戏
Aug 02 Javascript
关于Vue.js 2.0的Vuex 2.0 你需要更新的知识库
Nov 30 Javascript
JS常见疑难点分析之match,charAt,charCodeAt,map,search用法分析
Dec 25 Javascript
Vue filters过滤器的使用方法
Jul 14 Javascript
微信小程序swiper组件用法实例分析【附源码下载】
Dec 07 Javascript
浅谈VUE监听窗口变化事件的问题
Feb 24 Javascript
Angular6使用forRoot() 注册单一实例服务问题
Aug 27 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
最小化数据传输――在客户端存储数据
2006/10/09 PHP
php 深入理解strtotime函数的使用详解
2013/05/23 PHP
PHP之图片上传类实例代码(加了缩略图)
2016/06/30 PHP
PHP实现负载均衡session共享redis缓存操作示例
2018/08/22 PHP
在PHP中实现使用Guzzle执行POST和GET请求
2019/10/15 PHP
prettify 代码高亮着色器google出品
2010/12/28 Javascript
从零开始学习jQuery (三) 管理jQuery包装集
2011/02/23 Javascript
file控件选择上传文件确定后触发的js事件是哪个
2014/03/17 Javascript
详谈JavaScript 匿名函数及闭包
2014/11/14 Javascript
基于jquery ui的alert,confirm方案(支持换肤)
2015/04/03 Javascript
简介JavaScript中POSITIVE_INFINITY值的使用
2015/06/05 Javascript
详解JavaScript对象类型
2016/06/16 Javascript
详解Vue2.0之去掉组件click事件的native修饰
2017/04/20 Javascript
微信小程序封装http访问网络库实例代码
2017/05/24 Javascript
D3.js进阶系列之CSV表格文件的读取详解
2017/06/06 Javascript
Vue.js的动态组件模板的实现
2018/11/26 Javascript
微信小程序实用代码段(收藏版)
2019/12/17 Javascript
JS实现纸牌发牌动画
2021/01/19 Javascript
[01:09]DOTA2次级职业联赛 - 99战队宣传片
2014/12/01 DOTA
[01:57]DOTA2上海特锦赛小组赛解说单车采访花絮
2016/02/27 DOTA
python备份文件以及mysql数据库的脚本代码
2013/06/10 Python
Python中MySQLdb和torndb模块对MySQL的断连问题处理
2015/11/09 Python
python3 unicode列表转换为中文的实例
2018/10/26 Python
Python异步操作MySQL示例【使用aiomysql】
2019/05/16 Python
python程序中的线程操作 concurrent模块使用详解
2019/09/23 Python
Python GUI编程学习笔记之tkinter中messagebox、filedialog控件用法详解
2020/03/30 Python
python同时遍历两个list用法说明
2020/05/02 Python
Black Halo官方网站:购买连衣裙、礼服和连体裤
2018/06/13 全球购物
农药学硕士毕业生自荐信
2013/09/25 职场文书
毕业生的自我鉴定该怎么写
2013/12/02 职场文书
违纪检讨书2000字
2014/02/08 职场文书
升旗仪式演讲稿
2014/05/08 职场文书
2015年招聘工作总结
2014/12/12 职场文书
全家福照片寄语怎么写?
2019/04/02 职场文书
MySQL 常见存储引擎的优劣
2021/06/02 MySQL
Windows 64位 安装 mysql 8.0.28 图文教程
2022/04/19 MySQL