You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为DataTables实现加载进度条?进度条直接跳至100%

大数据量DataTables实现进度条的解决方案

问题根源

你当前代码的核心问题有两个:

  • forEach 不支持异步等待,所有循环迭代会被一次性触发,await setTimeout 只会阻塞单个回调函数,不会阻止整个循环执行,导致所有数据添加和进度条更新几乎瞬间完成,视觉上直接跳转到100%。
  • 逐条调用 table.row.add() 会频繁触发DataTables内部逻辑,5000条数据的场景下性能极低,也会让浏览器无暇更新进度条UI。

最优实现方案

核心优化点

  • 使用异步for循环替代forEach,确保每一步操作完成后再执行下一步,保证进度条逐步更新。
  • 分批加载数据,减少DataTables的DOM操作次数,提升性能的同时让进度条更新更平滑。
  • 确保UI线程有时间重绘,避免进度条卡顿或跳变。

完整代码实现

HTML部分

<link href="https://cdn.datatables.net/1.13.4/css/jquery.dataTables.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdn.datatables.net/1.13.4/js/jquery.dataTables.min.js"></script>

<div id="progress-bar" class="progress-bar-striped">
    <div style="width: 0%;">
        <p>0%</p>
    </div>
</div>

<table id="data" class="table display table-stripped">
    <thead>
        <tr>
            <th>ID</th>
            <th>Album ID</th>
            <th>Title</th>
            <th>URL Photo</th>
        </tr>
    </thead>
    <tbody></tbody>
</table>

CSS部分

.progress-bar-striped {
    overflow: hidden;
    height: 20px;
    margin-bottom: 20px;
    background-color: #f5f5f5;
    border-radius: 4px;
    box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);
}

.progress-bar-striped>div {
    background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
    background-size: 40px 40px;
    float: left;
    width: 0%;
    height: 100%;
    font-size: 12px;
    line-height: 20px;
    color: #000000;
    font-weight: bold;
    text-align: center;
    box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15);
    animation: progress-bar-stripes 2s linear infinite;
    background-color: #288ade;
}

.progress-bar-striped p {
    margin: 0;
}

@keyframes progress-bar-stripes {
    0% {
        background-position: 40px 0;
    }
    100% {
        background-position: 0 0;
    }
}

JavaScript部分

let handleProgressBar = (id, value, total) => {
    let percent = Math.round((value / total) * 10000) / 100;
    $(id + " > div").html(`${percent}%`);
    $(id + " > div").css('width', `${percent}%`);
}

// 初始化DataTables,禁用非必要功能提升加载性能
let table = $('#data').DataTable({
    ordering: false,
    searching: false,
    paging: false
});

// 每批加载的数据量,可根据性能调整
const BATCH_SIZE = 50;

fetch('https://jsonplaceholder.typicode.com/photos')
.then(res => res.json())
.then(async res => {
    const totalItems = res.length;
    let loadedItems = 0;

    // 分批循环处理数据
    for (let i = 0; i < totalItems; i += BATCH_SIZE) {
        const batch = res.slice(i, i + BATCH_SIZE);
        // 一次性添加整批数据
        batch.forEach(data => {
            table.row.add([
                data.id,
                data.albumId,
                data.title,
                data.url
            ]);
        });
        // 更新进度
        loadedItems += batch.length;
        handleProgressBar('#progress-bar', loadedItems, totalItems);
        // 留时间给浏览器更新UI
        await new Promise(r => setTimeout(r, 10));
    }

    // 加载完成后恢复DataTables功能并绘制表格
    table.ordering(true).searching(true).draw();
});

额外说明

  • BATCH_SIZE可按需调整:值越大加载速度越快,进度条更新间隔越长;值越小进度条越平滑,总加载时长略久。
  • 初始化时禁用排序、搜索等功能,能大幅降低大数据量下的初始加载开销,全部数据加载完成后再启用。
  • await setTimeout的等待时间是为了让浏览器有足够时间重绘UI,避免进度条无法实时更新。

内容的提问来源于stack exchange,提问作者Jordy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 22:03:08