解决Vue框架下proxySetter时间过长的问题
条评论最近在对公司项目进行性能优化时,发现Vue框架下的proxySetter函数使用时间过长:
这个时间花费也太猛了,竟然花了1点多秒,这个定位起来没有那么直接,因为这部分函数是同Vue框架执行的。不像公司开发人员自己写的函数,我就直接点进去,看他写的代码,瞄几眼就知道是哪几行代码有性能问题(大部分是在长数组里使用循环找东西,这种改用对象一下就解决了),直接上手改。
如果对Vue框架数据绑定原理有初步了解的话,可以从图中看到proxy、observe等等关键字可以联想到,就是数据绑定时花费了大量时间。
Vue框架采用数据劫持结合发布者-订阅者模式的方式,通过 Object.defineProperty() 来劫持各个属性的setter,getter,在数据变动时发布消息给订阅者,触发相应监听回调。当把一个普通 Javascript 对象传给 Vue 实例来作为它的 data 选项时,Vue 将遍历它的属性,用 Object.defineProperty() 将它们转为 getter/setter。在属性被访问和修改时通知变化。
显然,应该就是Vue框架对一个复杂对象进行数据绑定所导致的问题,举个例子:
1 | mounted(){ |
解决的办法有两个:1.不要把复杂的对象绑定到Vue实例里。2.让这个对象的所有字段变成non-configurable
,让Vue不再对其进行绑定操作:
1 | mounted(){ |
Vue实例里对复杂对象进行数据绑定,会导致严重的性能问题,除了会在proxySetter花费大量时间,同时由于复杂对象有可能经常变动导致频繁触发以及GC,各个环节都变得很慢。在调试工具里proxySetter往前找找执行了哪些函数,在这些函数里找到那个复杂对象进行处理就可以解决问题了。