发表于: 2019-10-07 22:47:01

1 894


今日完成的事

       完成消息列表页面的搭建

明日计划的事

       继续任务

收获

       看了下Vue 列表渲染性能优化的原理,其中有个比较重要的概念就是DOM元素移动,DOM 节点移动的性能开销非常大,因此减少 DOM 节点移动次数是算法的核心。当然开启 track-by='$index'不需要移动DOM元素,只需插入缺少的节点即可。

假如一个列表的 DOM 节点可以全部复用,那么列表的更新的核心就是 DOM 节点移动到合适的位置。

用点伪代码来演示下

old [1, 2, 3, 4, 5, 6, 7]

更新为

new [7, 6, 5, 4, 3, 2, 1]

先声明一下

假设这样移动他

但是这个算法会移动 new.length 次,几乎是最糟糕的情况,有时候节点在正确的地方并不需要移动。


在移动之前判断一下,他是不是在正确的位置。而这里对于是否处在正确的判断,是看他们的前一个元素是否相同。

可以在大部分情况下避免不必要的移动,比如对于

index=>0

只需要执行一次就可以了


再举一个类似的例子

看起来很简单啊,也只是需改动一次就可以得到想要的结果

index=>0

index=>1

old [2, 3, 4, 5, 6, 1, 7] index => 6

直到最后我们的发现,直到移动了7次才得到想要的结果,第一个元素每一次移动都向后冒泡,成功的混淆了每一次判断结果。

如果我们能忽略第一次移动,那么之后的每一次判断都会成功

old [1, 2, 3, 4, 5, 6, 7]

new [2, 3, 4, 5, 6, 7, 1]

index = 1

old [2, 3, 4, 5, 6, 7, 1] index = 6

这样才是预期的结果


现在 Vue 判断移动的条件是

DOM 移动的核心代码。Vue 声称实现了一些启发算法,以最大化复用 DOM 元素。这里的启发指的是执行 DOM 元素移动的条件,通过判断元素是否在正确的相对位置上,来于评估当前移动是否必要以及是否会造成愚蠢移动,没错,说的正是[1, 2, 3, 4, 5, 6,7] => [2, 3, 4, 5, 6, 7, 1]。


Vue 已经为我们做了大量无脑优化,主要在提高 DOM 元素的复用率和减少DOM 元素移动次数算法两方面,DOM 元素的移动算法优化开发者不能做什么,但在提高DOM元素的复用率仍给开发者留有优化余地。

但是优化方式也十分简单,即给v-for列表加一个 track-by 属性,提示Vue 如何判断对象时同一份数据,提高缓存命中率。甚至可以直接加 track-by="$index" 原位复用DOM元素,这种优化效率最高,但是副作用上文中也说了,会丢失原DOM元素的临时状态组件私有状态,因此在交互复杂的列表中可能会有意想不到的问题,这时使用非$index的track-by也可以做到尽可能的性能优化。

2.0中track-by改成了key。




返回列表 返回列表
评论

    分享到