Object.freeze()提升Vue.js中大型列表的性能【翻译+解读】

介绍

文章连接:vuedose.tips/tips/improv…
这个网站主打,简洁快速的分享一些关于Vue的tips。每周更新,会发到邮件上。正文是翻译,解读是我本身的相关理解。vue

正文

在开发过程当中,咱们常常须要获取一些对象,像users信息,列表items,文章信息等等,可是咱们不须要去修改这些信息。咱们只是把这些信息展现出来,或者放在vuexstate里面。以下代码所示ios

export default {
  data: () => ({
    users: {}
  }),
  async created() {
    const users = await axios.get("/api/users");
    this.users = users;
  }
};
复制代码

Vue默认会对每一个数组数据的每一层属性,添加双向数据绑定机制。当数组对象很是庞大时,消耗在这上面的双向数据绑定就越多。 由于,在这种场景下,咱们能够经过阻止Vue对这些数据添加双向数据绑定来提升一些性能。Object.freeze()就能作到这点。vuex

export default {
  data: () => ({
    users: {}
  }),
  async created() {
    const users = await axios.get("/api/users");
    this.users = Object.freeze(users);
  }
};
复制代码

记住在Vuex中也可这样使用axios

const mutations = {
  setUsers(state, users) {
    state.users = Object.freeze(users);
  }
};
复制代码

若是你须要改变这些信息,你能够建立一个新的被冻结的数组并赋值给他api

state.users = Object.freeze([...state.users, user]);
复制代码

解读

来深究一下为何Object.freeze()方法能够作到阻止Vue添加双向数据绑定机制

你们应该都知道Vue是经过Object.defineProperty()来修改属性描述符中的settergetter的,在getter中收集依赖,在setter的时候触发依赖。
在ES5开始,全部的属性都有了属性描述符。决定是否能够修改一个属性的描述符有两个:数组

  • Writable:决定是否能够修改属性的值;
  • 另外一个是Configurable:决定是否可使用Object.defineProperty()来修改属性描述符,而且也会禁止删除这个属性;

当这两个描述符同时为false时,意味着这个属性彻底是一个常量,Vue不能经过Object.defineProperty()来添加双向数据绑定。收集不了依赖,也就作不了双向数据绑定,就少添加不少watcher实例。
async

  • 执行Object.freeze()会执行Object.seal()并吧全部的属性的writable设置成false
  • Object.seal()则会调用Object.preventExtensions()并把configurable设为false
  • Object.preventExtensions()则会禁止对象添加新的属性。
    这一趟下来,基本上变成一个永久性不能加查删的对象了。我作了个草图,你们康康,帮助理解下。

最后还有一个疑问,state.users = Object.freeze([...state.users, user]);会不会触发视图更新。

答案是会。我亲自写demo测试过,从新赋值会触发更新。
是为何呢?
其实很简单,users变量是定义在data中的,在Vue初始化initState的时候,会遍历data中的全部属性,添加监听。也就是说咱们冻结的是users里面全部的属性,并无冻结Vue中data,因此替换users会触发双向数据绑定。性能

翻译或者理解有纰漏的,欢迎你们帮忙指正~测试

相关文章
相关标签/搜索