如何使用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 相关文章推荐
使Ext的Template可以解析二层的json数据的方法
Dec 22 Javascript
取选中的radio的值
Jan 11 Javascript
jquery删除指定子元素代码实例
Jan 13 Javascript
JavaScript操作select元素和option的实例代码
Jan 29 Javascript
深入理解angularjs过滤器
May 25 Javascript
javascript创建含数字字母的随机字符串方法总结
Aug 01 Javascript
bootstrap3使用bootstrap datetimepicker日期插件
May 24 Javascript
基于js 本地存储(详解)
Aug 16 Javascript
vue+elementUI实现表格关键字筛选高亮
Oct 26 Javascript
three.js利用射线Raycaster进行碰撞检测
Mar 12 Javascript
VUE使用 wx-open-launch-app 组件开发微信打开APP功能
Aug 11 Javascript
详解CocosCreator消息分发机制
Apr 16 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二分法在IP地址查询中的应用
2008/08/12 PHP
php中遍历二维数组并以表格的形式输出的方法
2017/01/03 PHP
Laravel框架实现利用监听器进行sql语句记录功能
2018/06/06 PHP
laravel框架实现后台登录、退出功能示例
2019/10/31 PHP
yii2.0框架场景的简单使用示例
2020/01/25 PHP
js类中的公有变量和私有变量
2008/07/24 Javascript
javascript的函数、创建对象、封装、属性和方法、继承
2011/03/10 Javascript
简单几行JS Code实现IE邮件转发新浪微博
2013/07/03 Javascript
JavaScript window.location对象
2014/11/14 Javascript
CascadeView级联组件实现思路详解(分离思想和单链表)
2016/04/12 Javascript
详解从买域名到使用pm2部署node.js项目全过程
2018/03/07 Javascript
vue中使用cookies和crypto-js实现记住密码和加密的方法
2018/10/18 Javascript
Vue.js子组件向父组件通信的方法实例代码详解
2018/12/10 Javascript
Vue前端项目部署IIS的实现
2020/01/06 Javascript
Python学习笔记之os模块使用总结
2014/11/03 Python
详解Python中类的定义与使用
2017/04/11 Python
python 设置输出图像的像素大小方法
2019/07/04 Python
Python绘制二维曲线的日常应用详解
2019/12/04 Python
Python 装饰器原理、定义与用法详解
2019/12/07 Python
python矩阵运算,转置,逆运算,共轭矩阵实例
2020/05/11 Python
解决CSS3 transition-delay 属性默认值0不带单位失效的问题
2020/10/29 HTML / CSS
基于 HTML5 WebGL 实现的垃圾分类系统
2019/10/08 HTML / CSS
暇步士官网:Hush Puppies
2016/09/22 全球购物
新加坡网上化妆品店:Best Buy World
2018/05/18 全球购物
乌克兰时尚鞋子和衣服购物网站:Born2be
2018/05/24 全球购物
Under Armour安德玛意大利官网:美国高端运动科技品牌
2020/01/16 全球购物
Weblogc domain问题
2014/01/27 面试题
abstract class和interface有什么区别?
2012/01/03 面试题
军训心得体会
2013/12/31 职场文书
财务简历的自我评价
2014/03/05 职场文书
幼儿园小班个人工作总结
2015/02/12 职场文书
2015年医院后勤工作总结
2015/05/20 职场文书
画展观后感
2015/06/17 职场文书
从事会计工作年限证明
2015/06/23 职场文书
《蜜蜂引路》教学反思
2016/02/22 职场文书
人物搭配车车超萌联名预备中 【咒术迴战】 ⨯ 【天竺鼠车车】 展开合作
2022/04/11 日漫