面试官推荐的Object.freeze优化千万数据渲染,效果竟然不如分块渲染?实

作者:佚名 时间:2025-11-10 17:59

字号

近来于技术领域范畴内,一个同前端性能优化相关的话题再度引致讨论,即当后端一次性返还千万条数据之际,前端渲染招致卡顿该通过何种方式予以解决。存在某位开发者回想起去年面试之时遭遇被问及此问题的情况,那时面试官所给出的方案是运用“Object.freeze”,然而就实际测试的结果而言,真的仅仅只有这一种办法吗?现今我们去亲测几种主流的优化方案,试探探看哪种相较于更加契合真实场景。

测试环境搭建

我们借助Vue3以及NestJS构建了测试环境,模拟了一千万条数据从接口返回至前端渲染的整个流程。于初始状态时,页面渲染消耗时长大约为30秒,操作界面呈现极度卡顿之势,几乎难以正常进行使用。测试数据涵盖了编号、名称以及状态字段,每一条数据均对应着一个列表项,借助浏览器开发者工具记录首屏时间、内存占用以及滚动流畅度。

把测试所使用的设备设定成了具备16GB内存以及Intel i7处理器的台式电脑,应用的浏览器是持有Chrome 115版本的,我们将所有的浏览器扩展都予以关闭,目的在于保证测试环境能够保持一致,借助多次反复地试验来求取平均值,切实尽力让结果可以精准地呈现出各个方案的实际展现情况。

Object.freeze方案

被面试官推荐的那个Object.freeze方法,借助冻结JavaScript对象这种方式,实现了对Vue为其增添响应式特性行为的阻止。经过实际测试所展示出来的情况表明,该方法能够把渲染时间由30秒左右缩短到12秒左右 ,同时让内存占用降低大约40%。之所以会这样,是由于Vue不再针对每条数据去创建代理对象,进而减少了计算资源的消耗 。

然而呢,该方案明显存在局限,尽管首屏时间得到了一定改善,可是那12秒的等待时间,依旧超出了用户能够接受的范围,当数据量持续增加的时候,页面还是会出现显著的卡顿现象,另外,因为数据失去了响应式,后续没办法达成数据的动态更新,制约了交互功能的达成 。

 



分块渲染方案

运用requestAnimationFrame达成分块渲染,把一千万条数据划分成每批500条,每次依次做渲染。此方法充分借助浏览器空闲时段去执行任务,防止长时间阻碍主线程。在测试里,页面于3秒内呈现出首屏内容,用户能够立马开展基本操作。

 

getMockData() {
  function generateMockData(amount) {
    const data: any = []
    for (let i = 0; i < amount; i++) {
      data.push({
        id: i,
        name: `User${i}`,
        timestamp: Date.now(),
        metadata: {}
      })
    }
    return data
  }
  const mockData = generateMockData(1000000)
  return mockData
}

持续随着后续数据加载,页面滚动之际仍会出现些许轻微卡顿。内存占用维持在较低水准,大约是初始方案的30%。该方案达成相对简易,兼容性不错,数据量并非特别极端时表现较为均衡,适合多数业务场景。

虚拟列表方案

作为终极解决办法的虚拟列表,只对可视区域里头的数据项予以渲染。我们有着基于Vue3所实现的虚拟列表组件,竟然把渲染时间给压缩到了0.5秒以内,而且那内存的占用仅仅是整个完整渲染的5%。不管数据量究竟有多么大,页面始终一直能保持流畅地滚动 。

其实现的原理,在于借助计算出滚动的位置,进而动态地去更新可视区域所对应的那个数据索引。那些容器的高度以及每一条项目的高度,是要先前就确定好或者进行估算的,对于非可视区域的数据,则是采用空白占位符予以填充。此方案是需要去处理滚动事件的,还要动态地计算样式,其实现的复杂度显著地高于前面的那两种方案。

 

const getData = async () => {
  const res = await fetch('/api/mock')
  const data = await res.json()
  userList.value = data.map((item: any) => Object.freeze(item))
}

方案效果对比

以测试数据而言,虚拟列表于各项指标里展现出最为出色的表现,首屏时间仅仅为0.5秒,内存占用大概是150MB,滚动进程全然流畅。分块渲染的首屏时间是3秒,内存占用为450MB,滚动之际偶尔会出现卡顿。Object.freeze方案的首屏需要12秒,内存占用700MB,滚动性能比较差。

于实现复杂度的层面而言,Object.freeze是最为简易的,仅仅只需一行代码即可达到。分块渲染这种方式则是需要去处理分批的逻辑,及其渲染的时机,它是属于中等难度级别的。虚拟列表这一方面需要实现完整的渲染逻辑,以及滚动计算两方面内容,其复杂度最高,故而建议使用成熟的开源库来达成,而不是依靠自行去实现 。

技术选型建议

 


于实际项目当中,技术方案选定要依照具体需求来结合,要是数据的数量处于万条以内的状况,Object.freeze能够当作快速的解决办法,当数据量达到十万级别的这种量的时候,分块渲染能够通过较好成效来平衡性能以及实现成本这个这方面,面对着百万级以上的数据这种量级时,虚拟列表是唯一能够行得通的方案处。

重要考量因素之中也包含着团队技术实力。虽说虚拟列表性能极为优异,然而其调试维护成本相对较高。实现难度与性能之间分块渲染取得相对较好的平衡效果,适合多数前端团队采用。不管选择哪一种方案,均应当建立性能监控机制,以此确保用户体验始终处于可控状态。

各位从事开发工作的人员于实际工作进程当中有没有碰到过类似这般的性能方面的问题呢,你们最终选用了哪一种用来优化的方案呀,其效果又是怎样的呢,欢迎在评论的区域分享你自身所拥有的实战经验,要是感觉这篇文章具备一定帮助的话,请进行点赞给予支持并且分享给更多的同行业人员哦!

 



 

责任编辑:CQITer新闻报料:400-888-8888   本站原创,未经授权不得转载
继续阅读
热新闻
推荐