• 性能优化——Object.freeze()提高Vue.js中大型列表的性能


    正文

    在开发过程中,我们经常需要获取一些对象,像users信息,列表items,文章信息等等,但是我们不需要去修改这些信息。我们只是把这些信息展示出来,或者放在vuex中state里面。如下代码所示

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

    Vue默认会对每个数组数据的每一层属性,添加双向数据绑定机制。当数组对象非常庞大时,消耗在这上面的双向数据绑定就越多。
    因为,在这种场景下,我们可以通过阻止Vue对这些数据添加双向数据绑定来提高一些性能。Object.freeze()就能做到这点。

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

    记住在Vuex中也可这样使用

    const mutations = {
      setUsers(state, users) {
        state.users = Object.freeze(users);
      }
    };
    

    如果你需要改变这些信息,你可以创建一个新的被冻结的数组并赋值给他

    state.users = Object.freeze([...state.users, user]);
    解读
    来深究一下为什么Object.freeze()方法可以做到阻止Vue添加双向数据绑定机制
    大家应该都知道Vue是通过Object.defineProperty()来修改属性描述符中的setter和getter的,在getter中收集依赖,在setter的时候触发依赖。

    在ES5开始,所有的属性都有了属性描述符。决定是否可以修改一个属性的描述符有两个:

    是Writable:决定是否可以修改属性的值;
    另一个是Configurable:决定是否可以使用Object.defineProperty()来修改属性描述符,并且也会禁止删除这个属性;
    当这两个描述符同时为false时,意味着这个属性完全是一个常量,Vue不能通过Object.defineProperty()来添加双向数据绑定。收集不了依赖,也就做不了双向数据绑定,就少添加很多watcher实例。

    执行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会触发双向数据绑定。

    直接来源:https://www.jianshu.com/p/56168a779849
    翻译来源:https://vuedose.tips/tips/improve-performance-on-large-lists-in-vue-js/

  • 相关阅读:
    查找大文件 & 索引节点(inode)爆满 解决办法
    技术领导力 —— 左耳听风 专栏读后感
    左耳朵耗子关于技术变现一文读后感
    html--前端jquery初识
    html--JavaScript之DOM (文档对象模型)
    html--前端JavaScript基本内容
    html--前端javascript初识
    html--前端css常用属性
    html--前端css样式初识
    html--前端基本标签内容讲解
  • 原文地址:https://www.cnblogs.com/osmind/p/13042402.html
Copyright © 2020-2023  润新知