Dynamic creation of large html table in javascript performance

前端 未结 7 1309
轻奢々
轻奢々 2020-12-02 23:30

I have an application which is used for data analysis and I\'m having a few performance issues with the creation of the table. The data is extracted from documents and it is

相关标签:
7条回答
  • 2020-12-03 00:05

    The way you are building your string will cause massive amounts of garbage collection.

    As the string gets longer and longer the javascript engine has to keep allocating larger buffers and discarding the old ones. Eventually it will not be able to allocate sufficient memory without recycling the remains of all the old strings.

    This problem gets worse as the string grows longer.

    Instead try adding new elements to the DOM one at a time using the jQuery manipulation API

    Also consider only rendering what is visible and implement your own scrolling.

    0 讨论(0)
  • 2020-12-03 00:08

    Displaying that many rows is causing the browser's rendering engine to slow down, not the JavaScript engine. Unfortunately there's not a lot you can do about that.

    The best solution is to just not display so many rows at the same time, either through pagination, or virtual scrolling.

    0 讨论(0)
  • 2020-12-03 00:13

    Per others suggestions (I'm not reputable enough to comment yet, sorry!), you might try the TableSorter plugin to handle only displaying a usable amount of data at a time.

    I don't know how it fares at very high numbers of rows, but their example data is 1000 rows or so.

    This wouldn't help with JS performance but would keep the burden off the browser renderer.

    0 讨论(0)
  • 2020-12-03 00:13

    Could try this...

    Improve Loops

    Improve String Concat

    var tmpLst = [];
    
    for (var i=0, il=data.length; i<il; i++) {
        var record = data[i];
        var recordId = record.id;
    
        tmpLst.push('<tr id="');
        tmpLst.push(recordId); 
        tmpLst.push('" class="'); 
        tmpLst.push(record.status);
        tmpLst.push('">');
        tmpLst.push('<td width="1%" align="center">');
    
    ...ect...
    
    
    }
    rows += tmpLst.join('');
    

    This might squeeze an extra bit of performance...

    var lstReset = i * lstReset.length;
    tmpLst[lstReset + 1]='<tr id="';
    tmpLst[lstReset + 2]=recordId; 
    tmpLst[lstReset + 3]='" class="'; 
    
    0 讨论(0)
  • 2020-12-03 00:14

    You can do couple of things to increase the performance:

    1. your rows variable is getting bigger and bigger so, don't store the html in one variable. solution can be $.each() function and each function you append the element into DOM. But this is minor adjustment.
    2. Html generating is good, but you can try DOM creating and appending. Like $('<tr></tr>').
    3. And finally, this will solve your problem for sure : use multiple ajax call in the first ajax call collect how many data is available and fetch approximately 1,000 or may be more data. And use other calls to collect remaining data. If you want, you can use synchronous call or Asynchronous calls wisely.

    But try to avoid storing the value. Your DOM size will be huge but it should work on moder browsers and forget about IE6.

    @fuel37 : Example

    function outputDocumentNew(data, doc_id) {
        //Variable DOM's
        var rowSample = $('<tr></tr>').addClass('row-class');
        var colSample = $('<td></td>').addClass('col-class');
        var spanSample = $('<span></span>').addClass('span-class');
        var inputButtonSample = $('<input type="button"/>').addClass('input-class');
    
        //DOM Container 
        var container = $('#documentRows');
        container.empty().append('<table></table>');
    
        //Static part
        var head = '<thead>\
                    <tr>\
                        <th width="1%" align="center">ID</th>\
                        <th width="1%" align="center">Status</th>\
                        <th width="70%">Name</th>\
                        <th width="2%">Actions</th>\
                        <th width="1%">Origin</th>\
                    </tr>\
                    </thead>';
        container.append(head);
    
        var body = $('<tbody></tbody>');
        container.append(body);
    
        //Dynamic part
        $.each(data, function (index, value) {
            var _this = this;
    
            //DOM Manupulation
            var row = rowSample.clone();
    
            //Actions
            var inpFailOne = inputButtonSample.clone().val('F').attr('rev', _this.id).addClass('failOne').click(function (e) {
                //do something when click the button.
            });
            var inpPromoteOne = inputButtonSample.clone().val('P').attr('rev', _this.id).addClass('promoteOne').click(function (e) {
                //do something when click the button.
            });
    
            row
            .append(colSample.clone().append(_this.id))
            .append(colSample.clone().append(spanSample.colne().addClass('status').append(_this.status)))
            .append(colSample.clone().append(spanSample.colne().addClass('name').append(_this.name)))
            .append(colSample.clone().append(inpFailOne).append(inpPromoteOne))
            .append(colSample.clone().append(_this.origin));
    
            body.append(row);
        });
    }
    

    in this process you need to create & maintain id's or classes for manipulation. You have the control to bind events and manipulate each elements there.

    0 讨论(0)
  • 2020-12-03 00:31

    Answering to get formatting

    What happens if you do

    for(var i in data){
        var record = data[i];
        var recordId = record.id;
        rows += '<tr id="' + recordId + '" class="' + record.status + '">';
        rows += '<td width="1%" align="center">' + recordId + '</td>';
        rows += '<td width="1%" align="center"><span class="status" rel="' + recordId + '"><strong>' + data[i].status + '</strong></span></td>';
        rows += '<td width="70%"><span class="name">' + record.name + '</span></td>';
        rows += '<td width="2%">';
        rows += '<input type="button" class="failOne" rev="' + recordId + '" value="F">';
        rows += '<input type="button" class="promoteOne" rev="' + recordId + '" value="P">';
        rows += '</td>';
        rows += '<td width="1%">' + record.origin + '</td>';
        rows += '</tr>';
    }//end for
    
    0 讨论(0)
提交回复
热议问题