JS渲染十万数据列表

10次阅读

共计 1002 个字符,预计需要花费 3 分钟才能阅读完成。

直入正题:假设有十万条数据的列表要展示,该如何优化?
如果直接上,不管你是一条一条插入,还是先存入 fragment 再一次性插入,白屏时间都在 6s+,浏览器应该是合并了 dom 更新操作,如果不做优化,并不会分批渲染。
注意:测试所用的 item 结构是极其简单的,一旦渲染的 item 是复杂结构那么渲染的时间倍增

item.innerHTML = <p><i>${text}</i></p><strong> 测试 </strong>;

  1. 优化一,分批渲染 requestAnimationFrame
    requestAnimationFrame 和 setTimeout 的区别就不多复述了,网上一大把。先渲染一部分,然后执行循环逻辑。但是这个部分到底是多少,需要自己调试了,我写的是 300,但不一定适用。
    const totalFn = () => {window.requestAnimationFrame(() => {if (i <= data.length) {computedHeight(data.slice(i, i + 300)); // 执行插入 dom 操作
          i += 300;
          totalFn();} else {root.style.height = max + 'px'}
      })
    }
    totalFn();
这样能做到秒开,无长时间白屏。

but, 如果只是这样就回答的太简单了点,可能面试官还希望更深入的解答,比如我十万条数据就算能秒加载,但是渲染复杂逻辑,说不定会卡卡的,因为页面元素太多了。在不考虑分页的情况下,如何进一步优化。

  1. 优化二,只渲染可视区范围内的 dom(只提供思路了)

这块涉及的交互就略复杂了,首先为了保证和一次性加载出来的效果一致,比如有滚动惯性, 需要计算总高度。
简单的玩法,每一个 item 是同样的高度,那么计算高度就很简单了,但是如果每个 item 的高度不同,那么要就需要隐藏计算(把 dom 插入隐藏域,而且需要采用优化一的手段,不然会卡),但是那样又会导致整个计算过程过于漫长,需要寻找到最适合的点。
得到高度后,绑定 scroll 事件,根据 scrollTop 的值,动态计算展示哪一块内容,为了保证位置,还需要在首部填充空白块占位。
仍然可能存在的问题,比如 scroll 触发的时机,scroll 在 ios 下是不能做到实时触发的,比如在惯性滚动过程中,触发不了 scroll 事件,可能会导致部分白屏(暂时没有想到如何解决),如果用 iscroll.js, 不知道能不能
模拟到原生的效果。

正文完
 0