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

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

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

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

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

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

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

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

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

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

相关推荐
晗夜未央1 小时前
任务队列反复失败,先分清重试、阻塞和结果待核对
开发语言·javascript
jktantan2 小时前
每个节点 41 字节:把一棵百万节点树拆进 14 个 typed array
前端·javascript·vue.js·算法·typescript
我命由我123452 小时前
访客系统形式(有用户概念、无用户概念)
java·开发语言·前端·javascript·python·产品运营·产品经理
程序员大阳3 小时前
副队长JavaScript教程(65)-详解JSON:轻量级数据交换格式
javascript·json·序列化·反序列化·stringify·parse
paopaokaka_luck5 小时前
基于springboot+vue的益暖微光公益服务平台(DeepSeek公益助手、善款信息追溯、志愿服务积分闭环、ECharts运营分析、活动状态自动流转)
java·前端·javascript·spring boot·mysql·架构·echarts
栀椩5 小时前
Electron 内嵌页面跨域问题(CORS/PNA)解决全记录
前端·javascript·electron
asaotomo5 小时前
截图识题、AI 讲解、笔记沉淀:Chrome 扩展体验
前端·chrome·笔记
SEO_juper5 小时前
Chrome 扩展一键查看当前页面 SEO 信息:不用切页面,点一下全出来
前端·javascript·chrome
Highcharts.js5 小时前
CSUN 2026|Highcharts无障碍数据与AI分享
javascript·人工智能·数据分析·highcharts·图表开发
系统集成-鹰翔5 小时前
ERP推单数据库怎么备份:SQLite WAL模式下只复制db文件为什么可能漏任务
javascript·数据库·经验分享·后端