Suggerimenti per l'ottimizzazione del codice javascript. un anno di datteri

5

Sto giocando con l'oggetto data, ho creato una funzione che genera un sacco di date e applica alcune funzioni ad ogni data.

Per un mese vale circa 2.5ms sul mio pc, ff e chrome, ma per un anno vale orribilmente lento, 17-50ms, non prevedibile affatto.

Questo mi ha fatto pensare, cosa sto sbagliando, perché l'imprevedibilità?

Che cosa faresti diverso, creando dinamicamente un valore di data e ora?

function MakeDateRange( begin, end, __func )
{
    begin = new Date(begin);
    end   = new Date(end);

    var len  =((end.getTime()-begin.getTime())/86400000)|0,
        i = 0,
        t = performance.now(),
        dates = [];

    __func = __func || function( date )
    {
        return new Date(date);
    }
    for(i; i <= len; i++)
    {
        dates.push(__func(begin));
        begin.setDate(begin.getDate()+1);
    }

    document.body.innerHTML += (performance.now()-t )+"<br />";
    return dates;
}


var dates = MakeDateRange( "2015 2 1 0:0:0 GMT+0100", "2016 2 1 0:0:0 GMT+0100" , function(date){

    var no = document.body.appendChild(document.createElement("div"));
        no.innerHTML = date;
    return no
});
    
posta MeganFoxObama 06.12.2015 - 07:05
fonte

1 risposta

2

Test delle prestazioni

Visita jackgiffin.com per i test delle prestazioni

Il codice

Bene, per prima cosa vorrei scrivere tutto l'HTML in una sola volta. Un'altra cosa è che userei insertAdjacentHTML in modo che gli attuali listener di eventi e altre parti virtuali del contenuto corrente del corpo non vengano tolti. Quindi, usando questa e molte altre micro-ottimizzazioni, ho triplicato le prestazioni del tuo codice (in chrome, almeno). La seguente funzione ottimizzata preserva la maggior parte delle funzionalità originali della tua funzione.

let currentRound = -1;
MakeDateRange = function( beginText, endText, __func ){
    'use-strict';
    const t = performance.now();
    let begin = new Date(beginText), end = new Date(endText),
        curRound = 'z' + ++currentRound,
        len  = ((end.getTime()-begin.getTime())/86400000)|0,
        i = -1,
        bodyHTML = '',
        dates;

    if (__func instanceof Function){
        while (i++ !== len)
            begin.setDate(begin.getDate()+1), bodyHTML += __func(begin, curRound);
        document.body.insertAdjacentHTML('beforeend',bodyHTML);
        perfs[1] = (performance.now()-t );
        return document.getElementsByName(curRound);
    }
    dates = new Array(len);
    while (i++ !== len)
       begin.setDate(begin.getDate()+1), dates[len] = new Date(begin);

    perfs[1] = (performance.now()-t );
    return dates;
};
dates = MakeDateRange(
    "2015 2 1 0:0:0 GMT+0100",
    "2016 2 1 0:0:0 GMT+0100" ,
    function(date, curRound){ return '<div name='+curRound+'>'+date+'</div>' }
);
console.log(dates);

Tuttavia, se inline __func , sarà ancora più veloce:

let currentRound = -1;
MakeDateRange = function( beginText, endText ){
    'use-strict';
    const t = performance.now();
    let begin = new Date(beginText), end = new Date(endText),
        curRound = 'z' + ++currentRound,
        template = '<div name="' + curRound + '">',
        len  = ((end.getTime()-begin.getTime())/86400000)|0,
        i = -1,
        bodyHTML = '',
        dates;

    while (++i !== len)
       begin.setDate(begin.getDate()+1), bodyHTML += template + begin + '</div>';

    document.body.insertAdjacentHTML('beforeend',bodyHTML);
    perfs[2] = (performance.now()-t );
    return document.getElementsByName(curRound);
};
dates = MakeDateRange(
    "2015 2 1 0:0:0 GMT+0100",
    "2016 2 1 0:0:0 GMT+0100"
);
console.log(dates);

Inoltre, ti consiglio vivamente di utilizzare let e const anziché var perché performance.now è disponibile da IE10 e let e const sono disponibili da IE11. IE10 è ottenibile solo con aggiornamenti specifici di Windows 7. Inoltre, la maggior parte degli utenti di Windows non ha installato alcun aggiornamento che significherebbe IE9 o, molto più comunemente, tutti gli aggiornamenti di Windows installati che significherebbe IE11. È improbabile che qualsiasi utente di Windows 7 con gli aggiornamenti giusti per IE10 visiterà il tuo sito, quindi potresti anche girare per IE11.

    
risposta data 10.07.2017 - 01:34
fonte

Leggi altre domande sui tag