前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >一次加载1w条数据的最优解是什么?

一次加载1w条数据的最优解是什么?

作者头像
爱吃大橘
发布2022-12-27 14:17:57
4470
发布2022-12-27 14:17:57
举报
文章被收录于专栏:前端笔记薄前端笔记薄

首先先说结果,虚拟列表最优秀。

下面是一些测试和分析。

目标在那里,走着走着就到了 点赞再看,手留余香,与有荣焉

前奏:大列表的痛

最新版Chrome version:100.

  • 一下子加载1w条总时间:382ms
  • setTimeout分页(100条)加载1w条总时间:1965ms
  • requestAnimationFrame分页(100条)加载1w条总时间:2156ms

测试代码如下:

代码语言:javascript
复制
/*
 * @Author: pym
 * @Date: 2022-04-27 12:07:41
 * @LastEditors: pym
 * @Description: TODO xxx
 * @LastEditTime: 2022-04-27 13:31:34
 */
// import _ from 'lodash';
import React, { useState, useEffect } from 'react';
import ReactDOM from 'react-dom';

import './index.less';

// 利用babel来写jsx 运行的时候会转换成createElement创建
function Element() {
    const [state, setState] = useState(false)
    useEffect(() => {
        const now = Date.now()
        let ul = document.getElementById('container');
        const total = 10000
        let curNumer = 0
        const key = 4
        const pageCount = 100
        switch (key) {
            case 0:
                // 一下子加载1w条总时间:382ms
                for (let i = 0; i < total; i++) {
                    let li = document.createElement('li');
                    li.innerText = ~~(Math.random() * total)
                    ul.appendChild(li);
                }

                console.log('JS运行时间:', Date.now() - now);
                setTimeout(() => {
                    console.log('总运行时间:', Date.now() - now);
                }, 0)
                break;
            case 1:
                // setTimeout分页(100条)加载1w条总时间:1965ms
                function loop() {
                    if (curNumer < total) {
                        for (let i = 0; i < pageCount; i++) {
                            let li = document.createElement('li');
                            li.innerText = ~~(Math.random() * total)
                            ul.appendChild(li);
                        }
                        curNumer = curNumer + pageCount
                        console.log('运行时间:', Date.now() - now, curNumer);
                        setTimeout(function () {
                            loop()
                        })
                    } else {
                        console.log('总运行时间:', Date.now() - now, curNumer);
                    }
                }
                loop()
                break;
            case 2:
                // requestAnimationFrame分页(100条)加载1w条总时间:2156ms
                function loop2() {
                    if (curNumer < total) {
                        for (let i = 0; i < pageCount; i++) {
                            let li = document.createElement('li');
                            li.innerText = ~~(Math.random() * total)
                            ul.appendChild(li);
                        }
                        curNumer = curNumer + pageCount
                        console.log('运行时间:', Date.now() - now, curNumer);
                        window.requestAnimationFrame(() => loop2())
                    } else {
                        console.log('总运行时间:', Date.now() - now, curNumer);
                    }
                }
                loop2()
                break;
            case 4:
                // 一下子使用DocumentFragment加载1w条总时间:382ms
                const documentFrag = new DocumentFragment()
                for (let i = 0; i < total; i++) {
                    let li = document.createElement('li');
                    li.innerText = ~~(Math.random() * total)
                    documentFrag.appendChild(li);
                }
                ul.appendChild(documentFrag)

                console.log('JS运行时间:', Date.now() - now);
                setTimeout(() => {
                    console.log('总运行时间:', Date.now() - now);
                }, 0)
                break;
            default:
                break;
        }
        // 将数据插入容器中



        return function clean() {
            console.log('clean')
        }

    }, [])
    return <div className="container">
        bigList
        <div id='container'></div>
    </div>

}
// 渲染dom元素 指定容器
ReactDOM.render(<Element />, document.getElementById('root'));

线上版本:代码片段

如果你需要首屏快的话,要用分页,其中requestAnimationFrame分页更为优秀,因为这个api会是系统调用的,刷新时机和屏幕刷新保持一致。setTimeout则不能保证一致。

至于加载总时间是一次性加载快,猜测是chrome做了优化。因为case 1的setTimeout是立即执行的和case 0 一下子全部加载应该是执行顺序一样的。但是case 0 更快,应该是Chrome做了对appendChild做了合并处理。为了测试是否因为chrome做了合并处理,我在case 4中使用了DocumentFragment,结果发现和case 0 的表现一致。暂且,这样理解。

但是它们就算加载结束也会在快速滚动时候出现时候白屏。这时候只能使用 虚拟列表 解决。

救星:虚拟列表

「前端进阶」高性能渲染十万条数据(虚拟列表)


参考文章:

https://juejin.cn/post/6844903982742110216

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-04-27,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前奏:大列表的痛
  • 救星:虚拟列表
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档