资讯专栏INFORMATION COLUMN

每日 30 秒 ⏱ 对海量数据进行切割

ShevaKuilin / 752人阅读

简介
数据分割、分页、异步操作、DOM优化

把数组按指定大小进行分组,可以用于分页、数据切割、异步操作数据。

// 该源码来自于 https://30secondsofcode.org
const chunk = (arr, size) =>
  Array.from({ length: Math.ceil(arr.length / size) }, (v, i) =>
    arr.slice(i * size, i * size + size)
  );
代码分析

Array.prototype.from 从一个类似数组或者可迭代对象中创建一个新的数组实例,类似数组 这个词可能很多人都不是很清楚,类似数组是 javascript 中一个神奇的对象,只要拥有 length 就算是类似数组了。

最常见的类似数组是函数中的 arguments 有长度和 arguments[0] 的调用方法,但是却没有数组的 push 等函数方法。利用 Array.prototype.from 则可以把 类似数组 转化为 数组。这个代码的巧妙之处在于用了 { length: 3 } 这样的对象来快速 生成数组,而 Array.prototype.from 的第二个参数会对刚生成的数组进行循环遍历相当于调用了 map

在循环遍历新生成数组时,使用了 Array.prototype.slice 的方法来实现了分割数据的效果,这个方法相当常用同学们可以记住它。

使用场景

假设现在有一个消息列表数组里面有一万条数据让你渲染到页面上,大部分人会直接遍历数组并拼接成 dom 一股脑的渲染到页面上,这样带来的后果是大量的 dom 操作会花费很多时间导致页面卡顿,且上下滑动页面时也会卡顿。

我们不妨换个角度来看这个问题无论是手机屏幕还是电脑屏幕用户可见的页面数据条目可能就十几条。那为什么我们要一次性渲染一万多条,而且用户也不见得会把所有数据都查看了。

那我们是否可以只渲染十几条数据,其他数据等用户滚动了某个高度时再进行下一个十几条数据的渲染。在分页操作中,chunk 就可以帮助我们快速的进行分页。

样式
.news > div {
    text-align: center;
    height: 50px;
}
结构

脚本
// 模拟生成 1万条数据,这里就利用了 Array.from 来快速生成数据
const originNews = Array.from(
    { length: 10000 },
    (v, k) => ({ content: `新闻${k}` })
)

// 需要插入的容器
const element = document.querySelector(".news")[0]

// 创建视图监听
const loadObserver = new IntersectionObserver((entries) => {
    // 如果不可见,就返回
    if (entries[0].intersectionRatio <= 0) {
        return;
    }

    // 判断是否有上一页和下一页
    const hasPrePage = page != 0
    const hasNextPage = page != news.length - 1

    const now = news[page]
    const pre = hasPrePage ? news[page - 1] : []
    const next = hasNextPage ? news[page + 1] : []

    // 传递锚点的坐标 和 当前页面显示的数据
    render(pre.length, [ ...pre, ...now, ...next ])
    
    // 判断是否需要翻页,且防止数组越界
    page = entries[0].target.className == "news-footer" || page === 0
        ? (hasNextPage ? page + 1 : page)
        : (hasPrePage ? page - 1 : page)
}, { threshold: [1] })

// 设置监听
loadObserver.observe(document.querySelector(".news-header"))
loadObserver.observe(document.querySelector(".news-footer"))

// 根据当前页面高度和新闻高度算出每一页可以放几条数据
let pageNum = Math.ceil(document.body.clientHeight / 50)
let page = 0 // 当前显示了第几页的数据
let news = chunk(originNews, pageNum) // 分页后的数据

// 渲染新闻 并 跳转到锚点
function render(last, data) {
    element.innerHTML = ""

    data.forEach((i, v) => element.innerHTML += v == last
        ? `
${i.content}
` : `
${i.content}
` ) window.location.href = "#news-herf" }
一起成长
在困惑的城市里总少不了并肩同行的 伙伴 让我们一起成长。

如果您想让更多人看到文章可以点个 点赞

如果您想激励小二可以到 Github 给个 小星星

如果您想与小二更多交流添加微信 m353839115

本文原稿来自 PushMeTop

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/102432.html

相关文章

  • 每日 30 ⏱ 该不该优雅

    showImg(https://segmentfault.com/img/remote/1460000018734296?w=900&h=500); 简介 可读性、性能、Spread、Reduce 在 优雅三连击 中有同学提到了 可读性 这个关键词,就小二个人的观点 在某个范围内使用比较常用到的小技巧,可以提升一定的可读性,文中提到的短路运算在初始化变量是提升可读性的,并且在很多提倡优化if 语句...

    JohnLui 评论0 收藏0
  • 每日 30 ⏱ 巧用可视区域

    简介 可视区域、页面优化、DOM节点多、图片懒加载、性能 可视区域是一个前端优化经常出现的名词,不管是显示器、手机、平板它们的可视区域范围都是有限。在这个 有限可视区域 区域里做到完美显示和响应,而在这个区域外少做一些操作来减少渲染的压力、网络请求压力。在 每日 30 秒之 对海量数据进行切割 中的使用场景,我们就是利用了 有限可视区域 只渲染一部分 DOM 节点来减少页面卡顿。 既然 可视区域 ...

    DevYK 评论0 收藏0
  • 每日 30 数组项目进行统计

    showImg(https://raw.githubusercontent.com/pushmetop/resource/master/30-seconds-for-everyday/count/poster.png); 简介 数组、统计、遍历 根据指定的方法或者参数对数组中的项目进行统计。 // 该源码来自于 https://30secondsofcode.org const countBy =...

    huayeluoliuhen 评论0 收藏0
  • 每日 30 ⏱ 唯一数据

    showImg(https://segmentfault.com/img/remote/1460000018795147?w=901&h=501); 简介 数组、对象、唯一、只出现一次、差集 取出两个对象数组中唯一的数据集,即差集。 // 该源码来自于 https://30secondsofcode.org const filterNonUniqueBy = (arr, fn) => arr....

    gityuan 评论0 收藏0
  • 每日 30 数据类型大乱炖

    showImg(https://segmentfault.com/img/remote/1460000018796041?w=900&h=500); 简介 字符串、数字、布尔值、Null、Undefined、对象、数组、函数、判断方法 JavaScript 中有两种数据类型,分别是基本数据类型和引用数据类型: 基本数据类型 引用数据类型 Number、String、Boolean、Null...

    meteor199 评论0 收藏0

发表评论

0条评论

ShevaKuilin

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<