宝哥软件园

详细说明Vue依赖集合带来的问题

编辑:宝哥软件园 来源:互联网 时间:2021-08-25

问题背景

我们的项目中有一个可视化的配置模块,它是通过go.js生成canvas来实现的,但是我们发现这个模块经常会导致标签页在浏览器中崩溃。当你打开chrome的任务管理器,进入这个页面内存和cpu会暴涨,内存往往会飙升到700 m以上,然而我们画布的实际像素只有500x500左右。根据一些粗略的计算,它只占1M的内存。这个计算过程可以参考100*100画布占用的内存。那么我们的7亿内存从何而来呢?

布局问题

我们可以使用chrome开发工具来分析我们的调用堆栈。在这里,我首先通过Performance帮助我们定位问题,这将帮助我们在过程中生成一些数据变化,包括js堆内存、dom节点号、动画帧等数据,如图所示:

这是切换到大画布模块的性能分析性能,可以看到它占用了472M的内存。下图折线图的蓝色部分显示了js堆内存的变化,而Main下面的黄色和紫色矩形框是我们的调用栈,上下部分按照时间一一对应。可以看到蓝色虚线是波动的,低点基本等于GC恢复后的高点,所以可以断定几乎不存在内存泄漏问题。然后我们可以放大看看。当记忆上升时,js做了什么,并寻找规则。

我们随机找到一个内存增长区域,可以看到在内存增长的过程中,与Observer相关的代码被调用的次数最多。但是这样看,我们无法理解观察者在做什么。此时,我们可以使用Memory选项中的Allocation Sampling,根据javascript函数查看内存分配情况,我们也记录了上面的操作。

这时,我们可以清楚地看到,这个观察者真的在工作。同时,我们可以看到这是vue的代码。点击右边的文件查看源代码,我们可以清楚的了解到vue是在执行依赖集合的操作。此时,一个观察器将被添加到属性中。那为什么我们在这里给守望者增加了这么多属性呢?看看代码,原来我在vue的数据选项中挂了一个go.js的实例,放入数据中的属性会被vue收集,但是这个实例有很多嵌套的属性,所有的属性都会加上watcher。事实上,我们只想简单地存储这个实例,以便我们以后调用它的相关方法。添加watcher对我们来说完全没有意义,那么如何避免这样的问题呢?

解决问题

在网上搜索相关解决方案,大概有以下几种:

在数据中定义的属性前添加$通知vue该属性不需要依赖收集,例如:JavaScript data(){ return { $goDiagram 3360 null } },但声明在模板中引用$ goDiagram的属性时找不到的错误将被报告。具体原因还没研究,有时间可以研究一下。未在数据中声明,但在赋值时直接声明了this.goDiagram=diagram。这也会遇到第一种方案的问题,模板会提示找不到goDiagram属性。不要在数据中声明它,而是使用$options来存储goDiagram,例如:export default { goDiagram 3360 null,mounted () {this。$选项。godiagram=XXX}}这应该是更好的方法。Vue官方还声明,$options是用来包含自定义属性的,比如我们通常介绍的常量或者枚举类型,我们不希望添加无意义的watcher,所以可以这样定义,在模板中引用时只需要{{$options.xxx}}。这种方法唯一的缺点是你不能像数据一样一眼就知道你定义了什么属性。我在项目中使用了第一种方法。修改后,内存消耗降低到原来的1/5到1/6。可以说效果非常好,浏览器再也不会死机了。

摘要

通过这样一个问题,我们主要可以学到两点:

如何通过chrome的开发者工具快速定位代码中的内存问题,不要盲目挂载数据选项中的属性。作为一种优化方法,我们可以用上面提到的几种方法来定义一些常数。以上是边肖介绍的Vue依赖集合带来的问题的详细解释和整合,希望对大家有所帮助。如果你有任何问题,请给我留言,边肖会及时回复你。非常感谢您对我们网站的支持!

更多资讯
游戏推荐
更多+