0
\$\begingroup\$

I load a table in a div using the .load() method. If I look on the console I see the times taken to display the table:

  • 4.98 seconds that firebugs says are spent "waiting" for a response (from a PHP backend)
  • 9.94 seconds receiving data.

During the second event I see that the browser throws an alert saying that the script is taking too long and asks if you want to continue. Then the browser freezes for a couple of seconds and after these two steps it displays the table and the browser starts working fine again.

I have attempted to optimize this code (it is the same as the previous question I posted) and the "waiting" time has moved from about 30 seconds to about 5. What I can't get rid of is the JS part of the script. With smaller tables, it still works fine but I have one that is 487 rows which still causes problems. The point is that the tables will grow each year by 12 columns and all the tables are expected to have at least 480/500 rows each.

How can I modify my JS to minimize its execution time? I believe that the issue is on the bottom of the page when I ask JS to iterate through the table to change some columns value row by row but I have no clue on how to write this better.

The table is built from this script:

<?php
require '../../session_handler.inc.php';
session_start();
$actusr = $_SESSION['id'];
$id_bp = $_GET['id_bp'];
$dett = $_GET['dett'];
$veicolo = $_GET['veicolo'];
if($veicolo != '0'){
    $veicolo_clause = " AND titolare='$veicolo'";
}else{
    $veicolo_clause = "";
}
require_once '../../global_functions.php';
require '../Classes/financial_class.php';
$f = new Financial;
$irr_mensile = array();
//$annoMin = $pdo->query("SELECT MIN(anno) AS anno FROM bp_flussi WHERE id_bp = '$id_bp'")->fetchColumn();
//$annoMax = $pdo->query("SELECT MAX(anno) AS anno FROM bp_flussi WHERE id_bp = '$id_bp'")->fetchColumn();
$annoMin = '2008';
$annoMax = '2017';
$vuoto = 0.00;
$creds = $pdo->query("SELECT * FROM bp_rows WHERE id_bp = '$id_bp'$veicolo_clause")->fetchAll();
$data_rif = $pdo->query("SELECT data_rifer FROM bp_head WHERE id = '$id_bp'")->fetchColumn();
?>
<script type="text/javascript">
$(document).ready(function(){
    resizeDiv();
    $("#spnmsg").fadeTo(200,0.1,function(){
    $(this).removeClass().addClass('spn_normal').html("Visualizzazione del business plan '<b><?php echo get_name('bp_head',$id_bp,'nome',$pdo);?></b>'.").fadeTo(900,1);
    });
    //$('#businessplan').DataTable();
});
</script>

<div class="titolo" id="title">
    <h1>JENIUS</h1>
    <h2>Business Plan '<?php echo get_name('bp_head',$id_bp,'nome',$pdo);?>' con data di riferimento <?php echo mysql2table($data_rif); ?> </h2>
</div>

<div class="pagina "id="contenuto">
<table class="report" id="businessplan">
    <caption class="report">Crediti inseriti nella sofferenza</caption>
    <thead>
    <tr>
        <th class="report">ID</th>
        <th class="report">Lotto</th>
        <th class="report">Sofferenza</th>
        <th class="report">Data acquisto</th>
        <th class="report">Cedente</th>
        <th class="report">Valore ammesso</th>
        <th class="report">Prezzo acquisto</th>
        <th class="report">Originator</th>
        <th class="report">Stato</th>
        <th class="report">Data chiusura</th>
        <th class="report">Motivo chiusura</th>
        <th class="report">Data ultimo incasso</th>
        <th class="report destra">% inc. prev.</th>
        <th class="report">Incassi effettivi</th>
        <th class="report">Incassi previsionali</th>
        <th class="report">IRR Mensile</th>
        <th class="report">IRR Annuale</th>
        <th class="report">NPV</th>
        <th class="report">Tipo flusso</th>
        <th class="report destra">Totale</th>
        <?php       
        for($anno = $annoMin; $anno<=$annoMax; $anno++){
        for($mese = 1; $mese <= 12; $mese++){
            $mese = sprintf("%02s", $mese);
            echo '<th class="report">'.$mese.'/'.$anno.'</th>';
        }
        }
        ?>
        <th class="report">Totale</th>
    </tr>
    </thead>
    <tbody>
    <?php
    //inizializzo l'array che contiene i valori dei totali di riga per mese per fare il totale di tabella
    $flusso_complessivo = array();
    for($anno = $annoMin; $anno<=$annoMax; $anno++){
        for($mese = 1; $mese <= 12; $mese++){
            $flusso_complessivo[] = $vuoto;
        }
    }
    $k = 0;
    $fluxes = $pdo->query("SELECT id_cre, periodo, incasso, spesa FROM bp_flussi WHERE id_bp = '$id_bp'")->fetchAll(PDO::FETCH_ASSOC);
    $flussi = array();
    foreach ($fluxes as $flux){
        $flussi[$flux['id_cre']][$flux['periodo']]= array('periodo'=>$flux['periodo'],'incasso'=>$flux['incasso'],'spesa'=>$flux['spesa']);
    }
    $incassi_prev_arr = array();
    $incassi_eff_arr = array();

    foreach($creds as $cred){    
    ?>
    <!-- dati generali dei singoli crediti -->
    <tr>
        <td class="report quarta" <?php echo ($dett == 1) ? 'rowspan="5"' : '' ?>><?php echo $cred['id_cre']; ?></td>
        <td class="report quarta" <?php echo ($dett == 1) ? 'rowspan="5"' : '' ?>><?php echo $cred['serie']; ?></td>
        <td class="report quarta" <?php echo ($dett == 1) ? 'rowspan="5"' : '' ?>><?php echo soff2name($cred['cod_soff'],$pdo); ?></td>
        <td class="report quarta" <?php echo ($dett == 1) ? 'rowspan="5"' : '' ?>><?php echo mysql2table($cred['data_acq']); ?></td>
        <td class="report quarta" <?php echo ($dett == 1) ? 'rowspan="5"' : '' ?>><?php echo prot2name($cred['cedente'],$pdo); ?></td>
        <td class="report quarta" <?php echo ($dett == 1) ? 'rowspan="5"' : '' ?>><?php echo number_format($cred['ammesso'],"2",",","."); ?></td>
        <td class="report quarta" <?php echo ($dett == 1) ? 'rowspan="5"' : '' ?>><?php echo number_format($cred['prezzo_acq'],"2",",","."); ?></td>
        <td class="report quarta" <?php echo ($dett == 1) ? 'rowspan="5"' : '' ?>><?php echo prot2name($cred['originator'],$pdo); ?></td>
        <td class="report quarta" <?php echo ($dett == 1) ? 'rowspan="5"' : '' ?>><?php echo $cred['stato']; ?></td>
        <td class="report quarta" <?php echo ($dett == 1) ? 'rowspan="5"' : '' ?>><?php echo ($cred['data_chius'] <> '0000-00-00') ? mysql2table($cred['data_chius']) : ''; ?></td>
        <td class="report quarta" <?php echo ($dett == 1) ? 'rowspan="5"' : '' ?>><?php echo chius2name($cred['caus_chius'],$pdo); ?></td>
        <?php
        $credito = $cred['id_cre'];
        $last_inc = $pdo->query("SELECT max(data_inc) FROM incassi_row WHERE id_cre = '$credito'")->fetchColumn();
        echo '<td class="report quarta" ';
        echo ($dett == 1) ? 'rowspan="5"' : '';
        echo '>';
        echo ($last_inc <> '') ? mysql2table($last_inc).'</td>' : '</td>';
        $perc_worst = $pdo->query("SELECT azioni_head.perc_worst FROM azioni_row JOIN azioni_head ON azioni_row.id_az = azioni_head.id_az
                                  WHERE id_cred = '$credito'")->fetchColumn();
        echo '<td class="report quarta destra" ';
        echo ($dett == 1) ? 'rowspan="5"' : '';
        echo '>'.$perc_worst.'%</td>';
        ?>
        <td class="report quarta" id="incassi_eff_<?php echo $k; ?>" <?php echo ($dett == 1) ? 'rowspan="5"' : '' ?>>incassi eff</td>
        <td class="report quarta" id="incassi_prev_<?php echo $k; ?>" <?php echo ($dett == 1) ? 'rowspan="5"' : '' ?>>incassi pre</td>
        <td class="report quarta" id="irr_mese_<?php echo $k; ?>" <?php echo ($dett == 1) ? 'rowspan="5"' : '' ?>>IRR Mensile</td>
        <td class="report quarta" id="irr_anno_<?php echo $k; ?>" <?php echo ($dett == 1) ? 'rowspan="5"' : '' ?>>IRR Annuale</td>
        <td class="report quarta" id="" <?php echo ($dett == 1) ? 'rowspan="5"' : '' ?>>NPV</td>
<!-- dettagli acquisto -->
    <?php
    $k = $k + 1;
    echo ($dett == 1) ? '<td class="report">Acquisto</td>' : '';
    echo ($dett == 1) ? '<td class="report destra total_to">Totala</td>' : '';

    $acquisti = array();
    $acquisto_tot = 0;
    for($anno = $annoMin; $anno<=$annoMax; $anno++){
        for($mese = 1; $mese <= 12; $mese++){
            $mese = sprintf("%02s", $mese);
            $inizio = $anno.'-'.$mese.'-01';
            $fine = $anno.'-'.$mese.'-31';
            if(($cred['data_acq']>=$inizio) && ($cred['data_acq']<=$fine)){
                $prezzo_acq = $cred['prezzo_acq'];
                echo($dett == 1) ? '<td class="report">-'.num2cur($prezzo_acq).'</td>' : '';
                array_push($acquisti,$prezzo_acq);
                $acquisto_tot = $acquisto_tot + $prezzo_acq;    
            }else{
                echo($dett == 1) ? '<td class="report">-'.num2cur('0.00').'</td>' : '';
                array_push($acquisti,'0.00');
            }
        }
    }
    echo ($dett == 1) ? '<td class="report total_from"><b>-'.num2cur($acquisto_tot).'</b></td></tr>' : '';
    ?>
<!-- dettagli incassi -->
    <?php
    echo ($dett == 1) ? '<tr><td class="report">Incasso</td>' : '';
    echo ($dett == 1) ? '<td class="report destra total_to">Totala</td>' : '';
    $incasso_tot = 0;
    $incassi = array();
    for($anno = $annoMin; $anno<=$annoMax; $anno++){
        for($mese = 1; $mese <= 12; $mese++){
            $incasso_eff = 0;
            $incasso_prev = 0;
            $mese = sprintf("%02s", $mese);
            $periodo = $mese.'/'.$anno;
            if(isset($flussi[$credito][$periodo])){
                //$key = array_search($flusso[$credito][$periodo]);
                $incasso = $flussi[$credito][$periodo]['incasso'];
            }else{
                $incasso = '0.00';
            }
            echo ($dett == 1) ? '<td class="report incasso _'.$credito.'">'.num2cur($incasso).'</td>' : '';
            $incasso_tot = $incasso_tot + $incasso;
            array_push($incassi,$incasso);

            if(strtotime(date("$anno-$mese-15")) > strtotime("$data_rif")){
                $incasso_prev = $incasso_prev + $incasso;
            }else{
                $incasso_eff = $incasso_eff + $incasso;
            }
        }
    }
    array_push($incassi_prev_arr,$incasso_prev);
    array_push($incassi_eff_arr,$incasso_eff);
    echo ($dett == 1) ? '<td class="report total_from"><b>'.num2cur($incasso_tot).'</b></td></tr>' : '';
    ?>

<!-- dettagli spese -->

    <?php
    echo ($dett == 1) ? '<tr><td class="report">Spesa</td>' : '';
    echo ($dett == 1) ? '<td class="report destra total_to">Totala</td>' : '';
    $spesa_tot = 0;
    $spese = array();
    for($anno = $annoMin; $anno<=$annoMax; $anno++){
    for($mese = 1; $mese <= 12; $mese++){
            $mese = sprintf("%02s", $mese);
        $periodo = $mese.'/'.$anno;
        if(isset($flussi[$credito][$periodo])){
            //$key = array_search($flusso[$credito][$periodo]);
            $incasso = $flussi[$credito][$periodo]['spesa'];
        }else{
            $incasso = '0.00';
        }

        echo ($dett == 1) ? '<td class="report spesa_'.$credito.'">-'.num2cur($spesa).'</td>' : '';
        $spesa_tot = $spesa_tot + $spesa;
        $spese[] = $spesa;
    }
    }
    echo ($dett == 1) ? '<td class="report total_from"><b>-'.num2cur($spesa_tot).'</b></td></tr>' : '';
    ?>
<!-- dettagli vendita -->

    <?php
    echo ($dett == 1) ? '<tr><td class="report">Vendita</td>' : '';
    echo ($dett == 1) ? '<td class="report destra total_to">Totala</td>' : '';
    $vendite = array();
    $vendita_tot = 0;
    for($anno = $annoMin; $anno<=$annoMax; $anno++){
        for($mese = 1; $mese <= 12; $mese++){
            $mese = sprintf("%02s", $mese);
            $inizio = $anno.'-'.$mese.'-01';
            $fine = $anno.'-'.$mese.'-31';      
            if(($cred['data_chius']>=$inizio) && ($cred['data_chius']<=$fine)){
                $prezzo_ven = $cred['prezzo_ven'];
                echo($dett == 1) ? '<td class="report">'.num2cur($prezzo_ven).'</td>' : '';
                array_push($vendite,$prezzo_ven);
                $vendita_tot = $vendita_tot + $prezzo_ven;  
            }else{
                echo($dett == 1) ? '<td class="report">'.num2cur('0.00').'</td>' : '';
                array_push($vendite,'0.00');
            }
        }
    }
    echo ($dett == 1) ? '<td class="report total_from"><b>'.num2cur($vendita_tot).'</b></td></tr><tr class="quarta">' : '';
    ?>
    <!-- righe totale -->
    <td class="report quarta">Totale</td>
    <td class="report quarta destra total_to">Totala</td>
    <?php
    $i = 0;
    $importo_tot = 0;
    $irr_array = array();
    for($anno = $annoMin; $anno<=$annoMax; $anno++){
    for($mese = 1; $mese <= 12; $mese++){
        $mese = sprintf("%02s", $mese);
        $importo = $incassi[$i] + $vendite[$i] - $spese[$i] - $acquisti[$i];
        echo ($importo >= 0) ? '<td class="report quarta success">'.num2cur($importo).'</td>' :
        '<td class="report quarta err">'.num2cur($importo).'</td>';
        $flusso_complessivo[$i] = $flusso_complessivo[$i] + $importo;
        array_push($irr_array, $importo);
        $i = $i + 1;
        $importo_tot = $importo_tot + $importo;
    }
    }
    echo '<td class="report quarta total_from"><b>'.num2cur($importo_tot).'</b></td>';

    ?>
    </tr>
    <?php
    foreach($irr_array as $value){
    if($value == 0){
        array_shift($irr_array);
    }else{
        break;
    }
    }
    for($i = count($irr_array)-1; $i>=0; $i-- ){
    if($irr_array[$i] == '0'){
        array_pop($irr_array);
    }else{
        break;
    }
    }
    if(count($irr_array)>0){
    $irr_singolo = $f->IRR($irr_array);
    if(is_null($irr_singolo)){$irr_singolo = '0.00';}
    }else{
    $irr_singolo = '0.00';
    }
    array_push($irr_mensile, $irr_singolo);

    ?>

    <?php    }   //fine del foreach credito    ?>
    <tr>
    <td class="report" colspan="20">Totale</td>
    <?php
    $i = 0;
    $totalissimo = 0;
    for($anno = $annoMin; $anno<=$annoMax; $anno++){
    for($mese = 1; $mese <= 12; $mese++){
        $valore = $flusso_complessivo[$i];
        echo ($valore >= 0) ? '<td class="report success"><b>'.num2cur($valore).'</b></td>' : '<td class="report err"><b>'.num2cur($valore).'</b></td>';
        $totalissimo += $valore; 
        $i = $i + 1;
    }
    }
    ?>
    <td class="report"><b><?php echo num2cur($totalissimo); ?></b></td>
    </tr>
    </tbody>
</table>
<script type="text/javascript">
    // Get the target column table cells.
    var target = $('.total_to');

    // Iterate over each cell in the source column and copy its text to the
    // corresponding cell in the target column.
    $('.total_from').each(function (rowIndex) {
        target.slice(rowIndex, rowIndex + 1).text($(this).text());
    });

    var irrs = <?php echo json_encode($irr_mensile); ?>;
    var incassi_prev_arr = <?php echo json_encode($incassi_prev_arr); ?>;
    var incassi_eff_arr = <?php echo json_encode($incassi_eff_arr); ?>;
    var num_creds = irrs.length;
    for(i=0; i<=num_creds; i++){
    sing_irr_mese = irrs[i];
    if(sing_irr_mese != '0.00'){ sing_irr_anno = 1 + sing_irr_mese; }else{ sing_irr_anno = '0.00';}
    sing_irr_anno = Math.pow(sing_irr_anno,12);
    if(sing_irr_anno != '0.00'){ sing_irr_anno = sing_irr_anno -1; }else{ sing_irr_anno = '0.00';}
    sing_irr_mese= sing_irr_mese * 100;
    sing_irr_anno = sing_irr_anno * 100;
    $('#irr_mese_'+i).number(sing_irr_mese, 2,',','.').append('%');
    $('#irr_anno_'+i).number(sing_irr_anno, 2,',','.').append('%');
    sing_incassi_eff = incassi_eff_arr[i];
    sing_incassi_prev = incassi_prev_arr[i];
    $('#incassi_prev_'+i).number(sing_incassi_prev, 2,',','.');
    $('#incassi_eff_'+i).number(sing_incassi_eff, 2,',','.');
    }
</script>

</div>
\$\endgroup\$
1
\$\begingroup\$

I am focusing on your last bit of JS, which is a bit to complicated in how its written. Heres how I would simplify it:

// Simpler and shorter variables. If you need to, add a comment explaining 
// what exactly they are. Since long variables can get incredibly repetitive
// and make your code illegible.
var _all = <?php echo json_encode($irr_mensile); ?>;
var _pre = <?php echo json_encode($incassi_prev_arr); ?>;
var _eff = <?php echo json_encode($incassi_eff_arr); ?>;
for(i = 0, length = _all.length; i < length; i++){
    // JavaScript handles conversion for you, so no need to check for 
    // "0.0". Also, don't repeat `sing_irr` the whole time.
    messe = _all[i] || 0;
    // Don't forget 0 equates to falsy, so use tertiary operators to
    // make your code more legible.
    anno  = messe ? Math.pow(1 + messe, 12) - 1 : 0;
    $('#irr_mese_'+i).number(messe * 100, 2, ',', '.').append('%');
    $('#irr_mese_'+i).number(anno * 100, 2, ',', '.').append('%');
    // instead of creating temporary variables here, simply use them 
    // directly - creating and destroying memory is slower and useless here.
    $('#incassi_prev_'+i).number(_eff[i], 2,',','.');
    $('#incassi_eff_'+i).number(_prev[i], 2,',','.');
}

Also, indentation is so important to make your code more legible and more fun to debug. I have tried to mash a couple of your line-by-line declarations into one line. This won't really speed up things a lot, though. Since this is so simple, I might even suggest not using jquery to get the elements but reducing it to standard JS.

\$\endgroup\$
  • \$\begingroup\$ applied your code but this doesn't give any appreciable performance improvement. Upvoted for some hints I got from your code \$\endgroup\$ – Lelio Faieta Jun 22 '15 at 12:55

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.