前端 BUG 录 - 因数组排序造成的卡顿

前端 BUG 录 - 因 lodashjs debounce 去抖优化造成的 bug
这两个 BUG 其实是同一个 BUG,怎么说呢?两个都没错,错就错在同时使用了。

因为我没处理边界,导致我会给一个大数组排序,造成了卡顿。然后卡顿造成了节流时间成为了笑话。

提问

因为这个 BUG 其实有好几个限定条件才会触发,所以我先来提几个问题

  1. 5000乱序的数据,排序需要多少时间? Array.prototype.sort
  2. 5000有序的数据,排序需要多少时间? Array.prototype.sort
  3. 对于有序数据,什么样的算法合适?
  4. 对于无序数据,什么样的算法合适?
  5. Array.prototype.sort 使用的是什么算法?

这些灵魂拷问,你有答案吗?

我当前的这个场景是分页拉取数据展示的时候要有序

如果你有答案,那可以知道,sort 对于我的这个场景不是很适用,插入排序应该是最优的选择

Array.prototype.sort 测试

地址:https://www.lilnong.top/static/html/user-session-list-virtual-insertsort-log-2.html

image.png

Array.prototype.shuffle = function() {
  let array = this;
  let len = array.length;
  for (let i = len - 1; i > 0; i--) {
    let j = Math.floor(Math.random() * (i + 1));
    [array[i], array[j]] = [array[j], array[i]];
  }
}
vm.list.shuffle();

console.time('a')
vm.list.sort((n,m)=>n.id-m.id);
console.timeEnd('a')

console.time('b')
vm.list.sort((n,m)=>n.id-m.id);
console.timeEnd('b')

console.time('c')
vm.list.sort((n,m)=>n.id-m.id);
console.timeEnd('c')

我遇到的问题&解决方案

Array.prototype.sort 代码有过升级

其实在新的浏览器中跑,我的方案也是能过去了,耗时也就 10ms 以下。
但是因为我们是 pc客户端,需要兼容 xp 系统,所以 chrome 的版本极低(40多)

新版本使用的其实是 timsort,timsort 是工业级算法,其混用插入排序与归并排序,二分搜索等算法,亮点是充分利用待排序数据可能部分有序的事实,并且依据待排序数据内容动态改变排序策略——选择性进行归并以及 galloping。什么是Timsort排序方法?

所以这里我们可以把 sort 改成 timsort。
image.png

只需要一次插入排序

https://www.lilnong.top/static/html/user-session-list-virtual-insertsort-log-2.html

因为我的数据是有序的,所以插入排序可以更快。
image.png

我依赖 lodash 的 _.sortedIndexBy 来实现,因为还有置顶规则,所以提供了一个计算权重的方法

image.png

微信公众号:前端linong

欢迎大家关注我的公众号。有疑问也可以加我的微信前端交流群。
clipboard.png


javascript-lNong
只此一生,何必从众

Read-Search-Ask

28k 声望
9.3k 粉丝
0 条评论
推荐阅读
「前端 BUG 录」遇到BUG应该如何排查
我们日常工作中虽然会遇到很多 BUG,我们也熟练掌握使用搜索引擎解决开发中的问题。但是当遇到线上 BUG 应该如何排查呢?我将我过往遇到的一些异常整理了出来,并将我遇到的干扰项以及问题点都做了详细记录。希望...

linong阅读 480

安全地在前后端之间传输数据 - 「3」真的安全吗?
在「2」注册和登录示例中,我们通过非对称加密算法实现了浏览器和 Web 服务器之间的安全传输。看起来一切都很美好,但是危险就在哪里,有些人发现了,有些人嗅到了,更多人却浑然不知。就像是给门上了把好锁,还...

边城31阅读 7.2k评论 5

封面图
涨姿势了,有意思的气泡 Loading 效果
今日,群友提问,如何实现这么一个 Loading 效果:这个确实有点意思,但是这是 CSS 能够完成的?没错,这个效果中的核心气泡效果,其实借助 CSS 中的滤镜,能够比较轻松的实现,就是所需的元素可能多点。参考我们...

chokcoco20阅读 2.1k评论 2

在前端使用 JS 进行分类汇总
最近遇到一些同学在问 JS 中进行数据统计的问题。虽然数据统计一般会在数据库中进行,但是后端遇到需要使用程序来进行统计的情况也非常多。.NET 就为了对内存数据和数据库数据进行统一地数据处理,发明了 LINQ (L...

边城17阅读 1.9k

封面图
【已结束】SegmentFault 思否写作挑战赛!
SegmentFault 思否写作挑战赛 是思否社区新上线的系列社区活动在 2 月 8 日 正式面向社区所有用户开启;挑战赛中包含多个可供作者选择的热门技术方向,根据挑战难度分为多个等级,快来参与挑战,向更好的自己前进!

SegmentFault思否20阅读 5.6k评论 10

封面图
过滤/筛选树节点
又是树,是我跟树杠上了吗?—— 不,是树的问题太多了!🔗 相关文章推荐:使用递归遍历并转换树形数据(以 TypeScript 为例)从列表生成树 (JavaScript/TypeScript) 过滤和筛选是一个意思,都是 filter。对于列表来...

边城18阅读 7.7k评论 3

封面图
你可能不需要JS!CSS实现一个计时器
CSS现在可不仅仅只是改一个颜色这么简单,还可以做很多交互,比如做一个功能齐全的计时器?样式上并不复杂,主要是几个交互的地方数字时钟的变化开始、暂停操作重置操作如何仅使用 CSS 来实现这样的功能呢?一起...

XboxYan21阅读 1.6k评论 1

封面图

Read-Search-Ask

28k 声望
9.3k 粉丝
宣传栏