美文网首页
在 Vue.js 中使用无响应数据提升性能

在 Vue.js 中使用无响应数据提升性能

作者: VioletJack | 来源:发表于2021-01-28 22:22 被阅读0次

    本文节选转载自
    作者:黄轶
    链接:https://juejin.cn/post/6922641008106668045
    来源:掘金

    使用 Non-reactive data 非响应式数据,你可以查看这个在线示例

    优化前代码如下:

    const data = items.map(
      item => ({
        id: uid++,
        data: item,
        vote: 0
      })
    )
    复制代码
    

    优化后代码如下:

    const data = items.map(
      item => optimizeItem(item)
    )
    
    function optimizeItem (item) {
      const itemData = {
        id: uid++,
        vote: 0
      }
      Object.defineProperty(itemData, 'data', {
        // Mark as non-reactive
        configurable: false,
        value: item
      })
      return itemData
    }
    复制代码
    

    还是前面的示例,我们先通过点击 Genterate items 按钮创建 10000 条假数据,然后分别在开启和关闭 Partial reactivity 的情况下点击 Commit items 按钮提交数据,开启 Chrome 的 Performance 面板记录它们的性能,会得到如下结果。

    优化前:

    image

    优化后:

    image

    对比这两张图我们可以看到优化后执行 script 的时间要明显少于优化前的,因此性能体验更好。

    之所以有这种差异,是因为内部提交的数据的时候,会默认把新提交的数据也定义成响应式,如果数据的子属性是对象形式,还会递归让子属性也变成响应式,因此当提交数据很多的时候,这个过程就变成了一个耗时过程。

    而优化后我们把新提交的数据中的对象属性 data 手动变成了 configurablefalse,这样内部在 walk 时通过 Object.keys(obj) 获取对象属性数组会忽略 data,也就不会为 data 这个属性 defineReactive,由于 data 指向的是一个对象,这样也就会减少递归响应式的逻辑,相当于减少了这部分的性能损耗。数据量越大,这种优化的效果就会更明显。

    其实类似这种优化的方式还有很多,比如我们在组件中定义的一些数据,也不一定都要在 data 中定义。有些数据我们并不是用在模板中,也不需要监听它的变化,只是想在组件的上下文中共享这个数据,这个时候我们可以仅仅把这个数据挂载到组件实例 this 上,例如:

    export default {
      created() {
        this.scroll = null
      },
      mounted() {
        this.scroll = new BScroll(this.$el)
      }
    }
    复制代码
    

    这样我们就可以在组件上下文中共享 scroll 对象了,尽管它不是一个响应式对象。

    其实之前在工作中也有同事遇到过类似的问题,后来通过 Object.freeze() 函数提升了一定的性能。

    相关文章

      网友评论

          本文标题:在 Vue.js 中使用无响应数据提升性能

          本文链接:https://www.haomeiwen.com/subject/cyzxtltx.html