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 浏览器的,其他的浏览器需要当事人进行充分测试才能保证其正确性。

相关推荐
Hilaku6 分钟前
我用AI重构了一段500行的屎山代码,这是我的Prompt和思考过程
前端·javascript·架构
Cxiaomu7 分钟前
React Native App 自动检测版本更新完整实现指南
javascript·react native·react.js
掘金安东尼1 小时前
前端周刊第439期(2025年11月3日–11月9日)
前端·javascript·vue.js
起这个名字1 小时前
微前端应用通信使用和原理
前端·javascript·vue.js
鹏多多2 小时前
Web使用natapp进行内网穿透和预览本地页面
前端·javascript
钱端工程师2 小时前
uniapp封装uni.request请求,实现重复接口请求中断上次请求(防抖)
前端·javascript·uni-app
茶憶2 小时前
uni-app app移动端实现纵向滑块功能,并伴随自动播放
javascript·vue.js·uni-app·html·scss
茶憶2 小时前
uniapp移动端实现触摸滑动功能:上下滑动展开收起内容,左右滑动删除列表
前端·javascript·vue.js·uni-app
Ayn慢慢2 小时前
uni-app PDA焦点录入实现
前端·javascript·uni-app
鹏仔工作室3 小时前
vue中实现1小时不操作则退出登录功能
前端·javascript·vue.js