使用 JavaScript 向表中添加 500,000 行而不会使页面崩溃

Posted

技术标签:

【中文标题】使用 JavaScript 向表中添加 500,000 行而不会使页面崩溃【英文标题】:Add 500,000 rows to a table using JavaScript without crashing the page 【发布时间】:2019-10-26 00:14:00 【问题描述】:

我有一个报表系统,用户单击报表,执行 SQL 并将结果显示在表格中。我遇到的问题是单个报告为该报告带回了超过 500,000 行。系统需要一段时间才能通过 AJAX 调用检索数据,但是一旦完成,浏览器就会在将 html 添加到页面时“挂起”。

我的问题是,有没有另一种方法可以将 HTML 添加到页面而不导致浏览器挂起?

var HTMLPRE = '<p class="text-center"><b id="lblReportStatus">Producing report...</b><br><small>Average time: ' + parseFloat($('#hidReportID').attr('data-avg')).toFixed(2) + ' seconds</small>' +
    '<br><small>Current time: <span id="divCurrentTimeTaken">0</span></small></p>';
window.CurrentTimer = 0;
$('#reportresults').html(HTMLPRE);
// start the timer
window.ProducingReportTimer = window.setInterval(function() 
    window.CurrentTimer++;
    $('#divCurrentTimeTaken').html(window.CurrentTimer + ' seconds');
, 1000);

$.post(window.routes['ReportWriter.ProduceReport'], FormData, function(resp, status) 
    if (status === 'success') 
        if (resp.code == '200') 
            $('#lblReportStatus').text('Generating report...<br>Please note your browser may become un-responsive.  Please wait for a few minutes if this happens.');
            ProduceReportTable(resp);
        
     else 
        alert("Unable to produce report.  Please contact support with the below information:\r\nStatus code" + status);
    
).fail(function(err, status) 
    alert("Unable to produce report.  Please contact support with the below information:\r\n" + err);
);
function ProduceReportTable(resp)
    var ReportHTML = '<div class="row"><div class="col-xs-12"><button class="btn btn-primary" id="btnExportExcel"><i class="fa fa-file-excel"> Excel</i></a></div>' +
        '</div><div class="col-xs-12"><div class="table-responsive" style="overflow-x: auto;">' +
        '<table class="table-hover table-striped table" id="tblReport">' +
        '<thead><tr>';
    // loop through the headers first
    $(resp.headers).each(function (idx, head) 
        ReportHTML += '<th>' + head + '</th>';
    );

    ReportHTML += '</tr></thead><tbody>';
    // loop through the data

    $(resp.rows).each(function (idx, row) 
        ReportHTML += '<tr>';
        $.each(row, function() 
            ReportHTML += '<td>' + (this instanceof Window ? '' : this) + '</td>';
        );
        ReportHTML += '</tr>';
    );
    ReportHTML += '</tbody></table></div></div>';
    $('#reportresults').html(ReportHTML);
    window.clearInterval(window.ProducingReportTimer);
    /*
    $('#tblReport').dataTable(
        deferRender:    true,
        /*scrollY:        200,*//*
        scrollCollapse: true,
        scroller:       true
    );*/

    // enable the excel button
    $('#btnExportExcel').on('click', function(e)
        e.preventDefault();
        let TableSource = document.getElementById('tblReport');
        var today = new Date();
        var dd = today.getDate();
        var mm = today.getMonth()+1; //January is 0!
        var yyyy = today.getFullYear();
        if(dd<10) 
            dd = '0'+dd
        
        if(mm<10) 
            mm = '0'+mm
        
        today = yyyy + '-' + mm + '/' + dd;
        GenerateXLSX(TableSource, true, resp.ReportName + '-' + today + ".xlsx")
    );

对不起,如果这个问题已经在别处得到解答,我已经搜索过,但找不到任何东西。

【问题讨论】:

你能在这个解决方案中引入分页吗?单个页面上的 500,000 行太多了。 甚至无限滚动。一次加载比以往更多的行通常是一个坏主意。 在意识到这是一个坏主意之前,您甚至不必考虑浏览器功能。一页中有 500000 行的任何内容都是无法使用的混乱。滚动条移动 1px 将使您移动约 500 个条目。无用。出于对所有美好事物的热爱,通过将结果分页到对用户更明智/有用的东西来改进用户体验。不可能所有这些信息都与您要传达的内容相关。 为了用户的利益,我不得不建议将数据表复制到您可以控制的其他地方,并限制结果并使用偏移量。这个的实施将取决于您的具体情况。 我认为如果试图显示 50 万行数据,任何程序都会挂起 - 除非你有一台内存很大的超级计算机 【参考方案1】:

没有。评论已经暴露了很好的答案;它的要点是,从 性能 点(没有什么可以正确呈现那么多数据),从 用户 点(没有人可以可能一次处理这么多数据)和从安全点(您的应用程序面临着巨大的 DoS 攻击的风险)。我可以想象的唯一用例是创建报告,在这种情况下,您应该导出 Excel/PDF 文档,而不是在 HTML 中显示它。

您应该实施分页和过滤选项来解决您的问题。如果您必须为此使用 javascript,请在​​您的应用上使用 jquery Datatables 和适当的 AJAX 端点。

【讨论】:

以上是关于使用 JavaScript 向表中添加 500,000 行而不会使页面崩溃的主要内容,如果未能解决你的问题,请参考以下文章

Netezza:如何向表中添加列

Python PyQt5 - 向表中添加行

如何在 React Hooks 中向表中添加行而不重复?

使用默认值向表中添加列

向表中添加了新列并减慢了整个数据库的速度。为啥?

vbscript 使用内容向表中添加新行