jquery foreach loop taking long time to append html

Viewed 213

I am appending about five thousand records with a jquery foreach loop but sometimes it takes a long time and makes the browser to be crashed.

        $.each(data, function(index, consignment) {
            
           
           if(consignment.delivery_runs !== null){
              var delivery_run_name = consignment.delivery_runs.name;
           }else{
               var delivery_run_name = '';
           }
           if(consignment.delivery_addresses != null){
               var delivery_name = consignment.delivery_addresses.company_name;
               var delivery_suburb = consignment.delivery_addresses.suburb;
               var delivery_postcode = consignment.delivery_addresses.postcode;
           }else{
            var delivery_name = '';
               var delivery_suburb = '';
               var delivery_postcode = '';
           }
           if(consignment.customers != null){
               var customer_name = consignment.customers.name;

           }else{
               var customer_name = '';
           }
           
        $('#consignment_table > tbody').append(`<tr class="consignment-row"><td><label class="kt-checkbox kt-checkbox--single kt-checkbox--solid">
                <input  type="checkbox"  class="kt-checkable check_con" name="check_consignment" data-id="${consignment.id}"  value="${consignment.id}">
                <span></span>
                </label></td><td>${consignment.id}</td><td>${$.trim(customer_name)}</td><td>${consignment.customer_reference}</td><td>${$.trim(delivery_name)}</td><td>${$.trim(delivery_suburb)}</td><td>${$.trim(delivery_postcode)}</td><td>${consignment.carton}</td><td>${consignment.pallet}</td><td>${consignment.space}</td><td>${consignment.weight}</td><td>${$.trim(run_sheet_name)}</td><td>${run_sheet_id}</td><td>${consignment.status}</td><td>${$.trim(delivery_run_name)}</td><td>${$.trim(getFormattedDate(consignment.delivery_date))}</td><td>${$.trim(getFormattedDate(consignment.required_delivery_date))}</td><td>${driver}</td><td>${vehicle}</td><td>${consignment.consignment_type}</td><td>${$.trim(consignment.product_types.name)}</td><td><a href="/consignments/show/${consignment.id}">View</a></td></tr>`);
    });

How I can improve this code.

2 Answers

use data.map to build one big HTML - and append it once

like so

$('#consignment_table > tbody').append(Object.values(data).map(consignment => 
{
    let result = '';
    //
    // build up the return string here using whatever logic you need
    //
    return result;
}));

You can put whatever logic to build the individual strings where indicated

here's your code

$('#consignment_table > tbody').append(data.map(
    consignment => {
        let delivery_run_name = '';
        let delivery_name = '';
        let delivery_suburb = '';
        let delivery_postcode = '';
        let customer_name = '';

        if (consignment.delivery_runs !== null) {
            delivery_run_name = consignment.delivery_runs.name;
        }
        if (consignment.delivery_addresses != null) {
            delivery_name = consignment.delivery_addresses.company_name;
            delivery_suburb = consignment.delivery_addresses.suburb;
            delivery_postcode = consignment.delivery_addresses.postcode;
        }
        if (consignment.customers != null) {
            customer_name = consignment.customers.name;
        }

        return `<tr class="consignment-row"><td><label class="kt-checkbox kt-checkbox--single kt-checkbox--solid">
            <input  type="checkbox"  class="kt-checkable check_con" name="check_consignment" data-id="${consignment.id}"  value="${consignment.id}">
            <span></span>
            </label></td><td>${consignment.id}</td><td>${$.trim(customer_name)}</td><td>${consignment.customer_reference}</td><td>${$.trim(delivery_name)}</td><td>${$.trim(delivery_suburb)}</td><td>${$.trim(delivery_postcode)}</td><td>${consignment.carton}</td><td>${consignment.pallet}</td><td>${consignment.space}</td><td>${consignment.weight}</td><td>${$.trim(run_sheet_name)}</td><td>${run_sheet_id}</td><td>${consignment.status}</td><td>${$.trim(delivery_run_name)}</td><td>${$.trim(getFormattedDate(consignment.delivery_date))}</td><td>${$.trim(getFormattedDate(consignment.required_delivery_date))}</td><td>${driver}</td><td>${vehicle}</td><td>${consignment.consignment_type}</td><td>${$.trim(consignment.product_types.name)}</td><td><a href="/consignments/show/${consignment.id}">View</a></td></tr>`;        
    }
));

I've fixed up a couple of other issues ... declaring var for the same variable multiple times ... it works, but is bad looking code

also, no need for if/else .. just set the value to blank, then just do an if

For possibly better performance ...

document.querySelector('#consignment_table > tbody').append(data.map(... same code as .map above ...).join(''))

i.e. native DOM method

Do a for loop instead of a foreach look. For each loops are less optimized due to them being newer.

Related