JS、VUE内存溢出问题的解决方案
1、学会使用devTool
Memory详解:
a、需要使用Memory来分析内存变化,至少记录两次内存快照,用于做内存变化比对。
举例:
编辑器有内存溢出,所以在打开前记录一次快照,打开编辑器等待加载完成,然后关闭编辑器,再记录一次快照。
两次快照间的内存差异,很大可能是内存溢出部分。当然,也有可能是一些依赖增长,此时多次打开关闭,观察内存变化,持续累积的部分必然是内存溢出。
b、关注detachDomElement
detach的元素表示这些DOM元素不在DOM树中,但是有被js对象所引用。
一般来说,这是内存溢出查找的主要入口。
查找的流程
1、找到shallow size较大的元素,一般来说会是HTMLDivElement,任意选中其中的一项,可以看到以下内容:
该清单表示它的被引用情况,此时,重点关注以下几项:
1、用户写的对象
2、监听
3、context上下文,上下文表示一些未被回收的函数中,有使用到相关对象
2、常见的解决方案
1 监听的问题
很多开发者在使用观察者模式后,忘了写对应的注销代码,这是大忌。不论是js、jquery、vue还是自己写的监听,都必须有对应的注销代码。
有on就得有off。
有addListener就得有removeListener。
举例:
在mounted的时候注册的监听,在beforeDestroy时候销毁。
2、VUE本身的问题
VUE挂载了大量的对象,有可能因为用户代码的介入,导致无法销毁,所以加入以下代码:
const cleanVnode=vnode=>{
if(vnode){
vnode.elm = null;
vnode._renderChildren=null;
vnode.children=null;
// vnode.context=null;
vnode.componentOptions=null;
}
}
Vue.mixin({
beforeDestroy() {
if(this.$el)
delete this.$el.__vue__;
},
destroyed() {
//为了内存,清空所有内容
this.$children = [];
this.$parent = null;
this._watchers = [];
this.$refs = {};
this.$root = null;
this.$slots = [];
this.$store = null;
cleanVnode(this._vnode);
cleanVnode(this.$vnode)
this._vnode = null;
this.$vnode = null;
if(this.$el)
delete this.$el.__ro__;
this.$el = null;
// this.$el=null;
this._watcher = null;
this._computedWatchers = {};
//ab-aui的内存溢出问题
this.popperElm=null;
if(this.$options){
this.$options.parent=null;
this._parentVnode=null;
this.$options=null;
}
},