Vue 动态排序

bubblesort-v2

上图每个竖线的高度由CSS属性height决定,而height由Vue的style绑定到列表对应索引的值的大小,所以高度由列表中数值大小决定,排序的速度由滑块控制。

其中的关键是等待Vue对界面的控制做出相应,不然就无法看到排序过程。JavaScript中setTimeout和Promise对于异步事件的优化有很大的作用,Vue.js正是通过macrotask和microtask对变化的数据进行了优化。正是这一点,如果直接对数据排序而不等待一个特定的时间则界面不会对数据的变化过程有反应,而是界面直接反应排序的结果。

如果频繁对Vue监视的数据做排序操作,Vue是怎么将数据的变化更新到界面上的?根据官方文档,对数据的更改会有一个队列,只有数据不再变更才会将数据的变化更新到界面上,这也正是Vue响应数据变化的性能保证。

偶然看到有大神使用排序操作测试setImmediate的性能,核心原理就是每次对界面的操作比如排序的一次交换过程响应到界面上后再执行下一步操作,测试的是JavaScript程序与界面的快速交互性能。可以查看setImmediate API demo

关于setImmediate API
Web开发人员通常使用setTimeout API来分解长时间运行的JavaScript操作。这种方法允许浏览器处理未完成的工作,例如布局和绘图,然后在回调JavaScript之前等待指定的时间段。在构建响应式Web应用程序时,它是一种重要的设计模式。

我使用Vue实现了一个简单的冒泡排序,在每次排序的交换过程中使用await和setTimeout等待界面完成相应,当setTimeout的时间为零时速度也没有多快,如果不使用await等待界面,那么界面是没有排序过程而是直接跳到完成状态。由于Vue设计为缓存数据更改对DOM的影响,在JavaScript忙碌的时候是不会绘制界面的。

Vue有个nextTick方法返回一个Promise表示界面已与内部数据完成同步,如果await这个Promise则会导致界面的卡死状态,也没有排序的过程,等待一段时间后直接到最终结果。

虽然是有setTimeout 0的方法来等待界面的响应,但是等待的时间和界面更新的关系不是很清楚。为什么setImmediate API demo的速度可以很快,而且界面的响应速度也很快?我认为不止是排序算法的原因,操作界面的方法也有一定的影响。总的来说要么控制style属性要么控制class属性进而影响界面的样式,这对于HTML并不能有很高的效率。

原文链接:https://marskid.net/2018/11/12/vue-bubble-sort/