Open Coffcer opened 8 years ago
mark
mark
vm.$compile在目前的版本中已经弃用了吧。
mark
@pramper 我用的1.0.24似乎还在,2.0+的compile已经写入文档,但功能和1.0+的已经不同
@Coffcer 哦~~~
你好,我试了下 Object.freeze() 方法,但是传到vue里面后报错,是什么原因?确定可行吗?我也想做这一块的性能优化。是不是Object.freeze()之后的对象,无法用v-for遍历?
@liming9515 freeze后,v-for必须自己指定track-by
@Coffcer 改完之后好像并没有变快,耗时没有多大改变,如果按照楼主的意思,5-10倍的空间,应该可以很快的,不知道是不是还有什么地方需要注意呢?
@liming9515 现在浏览器已经非常快了,所以这种优化只在大数据时或者webview里才有明显效果,我是将 10+ms 优化到 0.x ms,也有十倍了,但这种意义不大
@Coffcer 当模板的层次结构相对复杂的时候,比如v-for嵌套2-3层,其中还有v-if组合的情况,在初始化的时候,会出现非常严重的性能问题。不知道这一类的优化有没有接触过,或者你觉得可行的方案有吗?
@Coffcer 比如说我有以下的一个模板
<table id="myTable">
<tr v-for="row in rows">
<td v-for="col in cols">
<div v-if="col.format != null" class="grid-content">
{{ col.format(row) }}
</div>
<div v-else class="grid-content">
{{ row[col.name] }}
</div>
</td>
</tr>
</table>
如果我初始化的时候给这个对象 1000条row,5个col,会非常的慢,有什么方式优化吗?或者说我的写法出现了问题?
@liming9515 就算是原生js操作dom同时显示1000条row也不会很快,这可能要从产品形态入手,滚动加载或者翻页都行
update: 本文写于2016年,vue1.0时期,现在大部分已不适用
这个系列记录我在一年vue开发中总结的一些经验和技巧。
利用Object.freeze()提升性能
Object.freeze()是ES5新增的特性,可以冻结一个对象,防止对象被修改。
vue 1.0.18+对其提供了支持,对于data或vuex里使用freeze冻结了的对象,vue不会做getter和setter的转换。
如果你有一个巨大的数组或Object,并且确信数据不会修改,使用Object.freeze()可以让性能大幅提升。在我的实际开发中,这种提升大约有5~10倍,倍数随着数据量递增。
并且,Object.freeze()冻结的是值,你仍然可以将变量的引用替换掉。举个例子:
vue的文档没有写上这个特性,但这是个非常实用的做法,对于纯展示的大数据,都可以使用Object.freeze提升性能。
使用 vm.$compile 编译dom
$compile函数可以用来手动调用vue的方式来编译dom。在你需要处理某个jQuery插件生成的html或者服务端返回的html的时候,这个函数可以派上用场。但注意这是个私有api,随时都有可能变动,并且这种做法有违vue的理念。仅在不得已的时候使用。
合理使用track-by="$index"
track-by是vue为循环提供的优化方法,可以复用多次v-for中id相同的dom。如果你的数据没有一个唯一的id,也可以选择使用track-by="$index",但必须注意一些副作用。
举个例子:
这时候执行
this.list = [4, 5, 6]
,可以通过F12观察到,demo-1里的dom被全部删除,然后重新循环list生成dom,而demo-2不会删除dom,只是把他们的text格子修改为4,5,6。这就是track-by="$index"的效果,复用了两次v-for中$index相同的dom。这是一个很好的优化方法,但不是所有场景都适用,比如循环中包含表单控件或子组件时,由于dom并不会被删除重新生成,会导致第二次执行的v-for,原有表单控件的值不会改变,可以看这个例子: https://jsfiddle.net/jysboza9/1/
不要滥用Directive
网上有一种说法,认为dom操作都应该封装在指令中。实际开发中,我认为并不应该遵循这种教条。是否使用指令应该看你实现的是什么功能,而不是看是否操作了dom。比如说你想用vue封装一个jQuery插件,来看看下面哪种封装方法比较好:
个人认为无疑是第一种方法更好,datepicker是一个独立的组件,你并不需要关心他的内部是否操作了dom,是否封装了jQuery插件。
那么什么时候使用指令呢?来看一下浏览器原生提供的指令:
title属性为不同的标签提供tooltip功能,这就是一个指令。一个指令应该表示一个独立的功能,可以为不同的标签和组件提供相同的功能。
(待续...)