nodes 的值。
export default {
// ...
watch: {
data: {
handler() {
this.nodes = this.getNodes(this.data);
this.status = this.getStatus(this.nodes);
},
immediate: true,
},
// ...
},
// ...
};这种修改对于实现的功能是没有影响的,那么性能情况如何呢。
first rendering: 490.119140625ms
expanded change: 183.94189453125ms使用 Performance 工具尝试查找性能瓶颈。

我们发现,在
getNodes 方法调用之后,有一段耗时很长的
proxySetter 。这是 Vue 在为
nodes 属性添加响应式,让 Vue 能够追踪依赖的变化。
getStatus 同理。当你把一个普通的 JavaScript 对象传给 Vue 实例的
data 选项,Vue 将遍历此对象所有的属性,并使用 Object.defineProperty 把这些属性全部转为 getter/setter。对象越复杂,层级越深,这个过程消耗的时间越长。当我们存在 1w 个节点时,
proxySetter 的时间就会非常长了。这里存在一个问题,我们不会对
nodes 某个具体的属性做修改,而是每当
data 变化时重新去计算一次。因此,这里为
nodes 添加的响应式是无用的。那么怎么把不需要的
proxySetter 去掉呢?一种方法是将
nodes 改回计算属性,一般情况下计算属性没有赋值行为。另一种方法就是冻结数据。使用
Object.freeze() 来冻结数据,这会阻止修改现有的属性,也意味着响应系统无法再追踪变化。
this.nodes = Object.freeze(this.getNodes(this.data));查看 Performance 工具,
getNodes 方法后已经没有
proxySetter 了。
性能指标如下,对于初次渲染的提升还是很可观的。
first rendering: 312.22998046875ms
expanded change: 179.59326171875ms你可以通过改进后的示例 (Demo4) 来观察组件的性能损耗。
那我们能否用同样的办法优化










