eslint-plugin-prevent-memory-leak
v1.0.2
Published
prevent memory leak
Maintainers
Readme
eslint-plugin-prevent-memory-leak
内存泄露问题
传统的内存泄露方式和问题
如果在网上搜索前端内存泄露排查,出来的结果大概率是打memory快照,通过两次快照的对比,找到内存增加最多的项,沿着引用链路逐个分析。
但在如今的实际项目开发时,我们不仅会使用各类框架,还会大量引用第三方库,这导致出现内存泄露问题时,memory快照中会有大量无关信息,这使得内存泄露的排查就像大海捞针,即使找到了导致内存泄露的点,往往也要找到对应的代码,分析代码并排查问题。
静态代码分析
回头看内存泄露的成因,无非是开辟了一段内存空间,在组件/模块生命周期结束的时候没有及时回收,这类引用通常有:
- 全局变量
window、document上的变量及其绑定的事件 - 控制台中显示的打印的内容
- 对于
vue项目影响较大,vue项目会对相关数据包裹Proxy或者Object.defineProperty,使得该对象上存在对vue组件的引用,导致数据持续显示在控制台时,该组件占用内存不能完全释放。
- 对于
- 定义的全局对象
- 未销毁的定时器
如果能有工具,对以上常见的代码进行检测,无疑可以解决大部分问题
eslint插件
人力排查内存泄露问题,如果工具要做到同样的工作,仅需要仿照人力排查的流程,总结规律,将其转换为代码。eslint作为前端最常用的代码检测工具,它提供了基础的代码转AST->traverer以及标记功能,结合上面的思路,总结规律,实现eslint内存泄露代码静态检测插件无疑是个很好的选择。
使用和安装
安装
首先需要安装eslint ESLint:
npm i eslint --save-dev安装本插件 eslint-plugin-prevent-memory-leak:
npm install eslint-plugin-prevent-memory-leak --save-dev使用方式
添加 prevent-memory-leak 到 .eslintrc 配置
{
"plugins": ["prevent-memory-leak"]
}添加规则
{
"rules": {
"prevent-memory-leak/event-listener": "error",
"prevent-memory-leak/interval": "error",
"prevent-memory-leak/global-object-leak": "error",
}
}第三方库销毁规则配置较为复杂,因为需要用配置模拟第三方库导入、销毁的过程,具体参考文档第三方库销毁规则
全局对象内容挂载、卸载检测规则(global-object-leak),由于向对象上挂载、卸载掉方式太多,很难全部列举并排查,例如如下写法:
const arr = []
const f = (i, j)=>{
arr[i] = j
return ()=>{
arr = arr.filter(j>1)
}
}仅凭代码,很难判断调用f时,arr[i] = j到底只是修改值还是改变了数组长度,如果一直增加arr的长度,那么无疑是内存泄漏。同时,arr = arr.filter(j>1)操作也无法判断是不是真的减少了arr长度(实际上,这种情况更推荐用Set,删除时时间复杂度仅为O(1),且更容易确定挂载的数据已被删除),因此global-object-leak规则只处理了主流的挂载(如push)、卸载方法(如splice,直接赋空数组等)
整体详细使用、设计文档,参考文件夹内存泄漏规则,后续新增特性持续更新在此文件夹中
目前支持的规则
- event-listener
- interval
- global-object-leak
- import-lib-dispose
