You need to enable JavaScript to run this app. 如何使用Ajax与jQuery传输大数据量并优化批量入库与大文件上传性能
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Ajax与jQuery传输大数据量并优化批量入库与大文件上传性能

现有实现的核心性能瓶颈
  • 单条数据触发独立HTTP请求:1万条数据对应1万个POST请求,受浏览器同域名并发连接数硬限制(通常6-8个),请求会在浏览器端形成排队队列,随着连接占用不释放,越到后期队列堆积越严重,就会出现明显降速
  • 事件重复绑定:#clear元素的click事件被写在setInterval的执行逻辑里,每100ms执行一次就多绑定一次同样的处理逻辑,运行1000次就绑定了1000次,一次点击会触发上百次重复清空操作,内存占用持续上涨
  • 定时触发逻辑无等待:setInterval不管上一次AJAX有没有收到响应,到点就强制发新请求,实际请求发送速度远超出浏览器和服务器的处理能力,队列越攒越多
  • 无节制DOM渲染:每收到一个响应就往#result容器append一个新DOM节点,同时触发一次滚动动画,1万次操作就会生成1万个DOM节点,页面渲染压力会随节点数增长指数上升
  • 数据库操作开销过高:单条请求单独建立数据库连接、执行一次INSERT、提交一次事务,1万次流程的连接和事务提交开销就会吃掉90%以上的运行时长
落地优化方案

前端代码优化

  • 改用分批传输替代单条请求:将前端解析完成的结构化数据按固定大小切分批次(比如每50条为一组),一次性把整组数据作为请求体发给后端,1万条数据仅需200次请求,直接把HTTP请求总量降低98%
  • 替换定时触发为递归请求:等上一批请求的响应完全接收、处理完成后,再触发下一批请求的发送,从根源上避免请求队列堆积
  • 事件绑定前置到初始化阶段:把#clear的点击逻辑只绑定一次,不要再嵌套在循环/定时逻辑内部,杜绝重复绑定导致的内存泄漏
  • 批量DOM渲染:把每个批次的处理结果先拼接成完整HTML片段,一次性插入到结果容器中,最后统一做一次滚动到底的动画,把DOM操作次数从1万次降到几百次

优化后的前端参考代码:

$(document).ready(function () {
    // 全局任务状态标识
    let isPaused = false;
    const BATCH_SIZE = 50; // 可根据实际网络情况调整每批大小
    let currentPos = 0;
    let totalSuccess = 0;
    let totalFail = 0;
    let parsedRows = [];
    let sharedParams = {};

    // clear按钮绑定只执行一次
    $('#clear').click(function () {
        isPaused = true;
        $('#title').val('');
        $('#date').val('');
        $('#csvfile').val('');
        $('#result').empty();
        $(".loader").css('display','none');
    });

    $('#csv').on('submit',function (e) {
        e.preventDefault();
        // 保留原有表单校验逻辑
        // ... 原校验代码块

        const file = document.getElementById('csvfile').files[0];
        const reader = new FileReader();
        reader.readAsText(file);

        reader.onload = function(event){
            // 保留原有CSV前端解析逻辑,解析完成的行数据存入parsedRows
            // ... 原CSV解析代码块
            parsedRows = data;
            currentPos = 0;
            totalSuccess = 0;
            totalFail = 0;
            isPaused = false;
            sharedParams = {title: $('#title').val(), date: $('#date').val()};
            $('.loader').css('display','inline-block');
            // 启动批次请求
            sendNextBatch();
        }
    });

    // 递归发送批次请求,不占用多余并发
    function sendNextBatch() {
        // 任务终止条件
        if (isPaused || currentPos >= parsedRows.length) {
            $(".loader").css('display','none');
            $('#result').append('<span class="success">Fin d\'execution du script</span>');
            return;
        }
        // 截取当前批次数据
        const currentBatch = parsedRows.slice(currentPos, currentPos + BATCH_SIZE)
                                        .map(item => ({...item, ...sharedParams}));
        $.ajax({
            url: "/admin/add/action/",
            type: "POST",
            data: {batch_payload: JSON.stringify(currentBatch)},
            cache: false,
            dataType: "json",
            success: function (resp) {
                // 拼接整批的HTML片段一次性插入
                let fragment = '';
                resp.row_results.forEach((row, idx) => {
                    const globalIndex = currentPos + idx + 1;
                    fragment += `<span class="${row.color}"> n° ${globalIndex}<br> ${row.msg} </span>`;
                    row.color === 'success' ? totalSuccess++ : totalFail++;
                });
                $('#result').append(fragment);
                // 统一滚动到底部
                $('#result').animate({ scrollTop: $('#result')[0].scrollHeight }, 50);
                // 指针移到下一批,继续发请求
                currentPos += BATCH_SIZE;
                sendNextBatch();
            },
            error: function () {
                $(".loader").css('display','none');
                $('#result').append(`<span class="error">网络异常,任务暂停。已成功导入${totalSuccess}条,失败${totalFail}条</span>`);
            }
        });
    }
});

后端逻辑优化

  • 接收到前端传的批次JSON数据后,不要逐条建立数据库连接、逐条提交事务:在同一个数据库连接、同一个事务内,执行批量INSERT语句完成整批数据的写入,把数据库操作的开销降到最低
  • 逐行完成数据校验和写入后,把每行的处理结果(成功/失败状态、对应提示文案)整理成数组,一次性返回给前端即可
  • 针对之前反馈的大CSV上传慢的问题:这套方案是在浏览器端完成CSV全量解析,根本不需要把原始CSV文件上传到服务器,仅需要传解析后的结构化JSON数据,1万条数据对应的传输体积通常仅几百KB,完全不存在大文件等待上传过长的问题
优化效果对比
  • 原方案:1万条数据对应1万个请求,单条独立数据库操作,1万次DOM渲染,整体运行时长远超合理范围,后期请求堆积会出现明显卡顿
  • 优化后:1万条数据对应约200次请求,整批批量数据库写入,200次批量DOM渲染,整体运行速度平稳,没有请求堆积导致的降速问题,整体运行时长可降到原方案的1/20以下

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.28 10:36:03