Chrome 中当离开当前我写的 tab 时,内存居然增加了

不知道你是否在工作中遇到过,当你离开浏览器 tab 的时候,可能你去干其他事情去了,有可能你打开网页,下班的时候忘记关了,电脑也忘记关了,但很不幸的事,当你再次打开 tab 的时候发现页面已经崩溃了,或者页面变得比之前更卡了。

当我遇到这个问题的时候,我第一时间想到的是,内存泄露;于是我打开了内存分析工具,我足足分析了一个小时也没有发现内存存在泄露,每一次内存释放都能回到之前的内存量,于是我开始困惑了,于是我便开始分析代码,看了好一会儿也没发现有啥端倪。这个时候我便放下之前的方式,想想之前线上会不会存在这样的问题,于是我打开线上环境,进行了测试,但是还是一无所获。于是我告诉了测试,让测试测试之前的版本。哪天下班了,测试像往常一样操作,当再次上班的时候发现问题不存在。然后我便开始分析新增的代码,不知道找了多久,把所有的怀疑都验证了,都不是问题的关键。一次偶然的机会让我察觉到了问题的存在。

因为我是一直开着这个性能检测器的。我苦思冥想也想不出,我便一边百度一边思考;这次很意外,我思考的比较久,当我再次回到这个界面的时候,发现上面的 JS 推大小 居然变大了很多,但是不一会儿内存又回到了正常水平,于是我就开始怀疑是因为离开了这个页面导致的;接下来我便开始刻意离开页面,然后观察内存使用情况,发现果然如此。我们的代码逻辑是一直接收 base64 的照片,然后渲染出来,看起来就像一个视频,我们的 base64 的照片是设备上报来的,要想设备上报这些数据,需要使用串口跟设备建立连接。但是当我离开界面经过一段时间再次回来的时候,即便我断开与设备的连接,但是图像仍然一直在动,说明此时还有很多逻辑没有处理,一直被堆积,所以即便切断了来源,水还是一直在流,也就是离开页面以后水是流在蓄水池里面,并没有直接消化掉。基于这个结论我再次分析了代码,最后把代码锁定在下面这几行:

JavaScript 复制代码
// 模拟源源不断的水
setInterval(() => {
  console.log(i ++)
  requestIdleCallback(() => {
    console.log("这里处理图片的相关操作")
  })
}, 2000)

其中对图片的逻辑操作由于存在一定的逻辑,担心慢,也是因为出现过慢的情况(其实后面排查发现是设备导致的慢,跟我这边无关,只不过代码已经改了),于是我就想不要采用同步的方式执行,而是改成异步,但是我又不想使用 setTimeout ,于是想到使用这个 requestIdleCallback 来执行,但是我对这个 api 的理解仅仅停留在能调用的水平,不知道的是,这个 apitab 标签处于非激活状态下时,回调不会被执行。那在非激活状态下这些回调怎么处理呢,很简单就是将所有的回调存起来,当 tab 再次激活的时候执行。

其中 127 这个就是当从未激活到激活时迅速消化掉的日志。如果你的回调里面处理的逻辑不多,有时候你是察觉不到的,因为你切回来的瞬间几乎就能消化掉之前的。只有长时间处于非激活状态,你才能看出内存的变化。如果非要使用这个 api ,一定要配合这个 api 的第二个参数,也就是 option 。把代码改成下面这样就不会存在问题了,当然对于这种代码最好还是不要采用这样方式来解决。

JavaScript 复制代码
// 模拟源源不断的水
setInterval(() => {
  console.log(i ++)
  requestIdleCallback(() => {
    console.log("这里处理图片的相关操作")
    // 这里新增一个超时的参数
  }, {timeout: 100})
}, 2000)

如果这样,即便我们的 tab 处于非激活状态也会被执行。,当然这并非保险的做法,对于我的需求来说,最好不要使用这种办法,如果真的很费时,那么采用 setTimeout 就很不错。

由于我只是在 Chrome 中进行测试和操作,所以以上都是 Chrome 浏览器的,其他的浏览器需要当事人进行充分测试才能保证其正确性。

相关推荐
别拿曾经看以后~16 分钟前
【el-form】记一例好用的el-input输入框回车调接口和el-button按钮防重点击
javascript·vue.js·elementui
川石课堂软件测试22 分钟前
性能测试|docker容器下搭建JMeter+Grafana+Influxdb监控可视化平台
运维·javascript·深度学习·jmeter·docker·容器·grafana
科技探秘人31 分钟前
Chrome与火狐哪个浏览器的隐私追踪功能更好
前端·chrome
科技探秘人32 分钟前
Chrome与傲游浏览器性能与功能的深度对比
前端·chrome
JerryXZR37 分钟前
前端开发中ES6的技术细节二
前端·javascript·es6
problc1 小时前
Flutter中文字体设置指南:打造个性化的应用体验
android·javascript·flutter
Gavin_9151 小时前
【JavaScript】模块化开发
前端·javascript·vue.js
懒大王爱吃狼2 小时前
Python教程:python枚举类定义和使用
开发语言·前端·javascript·python·python基础·python编程·python书籍
待磨的钝刨3 小时前
【格式化查看JSON文件】coco的json文件内容都在一行如何按照json格式查看
开发语言·javascript·json
守城小轩8 小时前
Chromium127编译指南 Mac篇(五)- 编译Chromium
chrome·chrome devtools·指纹浏览器·浏览器开发