Errori Javascript comuni che incidono gravemente sulle prestazioni? [chiuso]


10

In un recente MeetUp di UI / UX a cui ho partecipato, ho dato un feedback su un sito Web che utilizzava Javascript (jQuery) per la sua interazione e interfaccia utente: erano animazioni e manipolazioni abbastanza semplici, ma le prestazioni su un computer decente erano orribili.

In realtà mi ha ricordato molti siti / programmi che ho visto con lo stesso problema, in cui alcune azioni distruggono assolutamente le prestazioni. È principalmente in (o almeno più evidente in) situazioni in cui Javascript è quasi in sostituzione di Flash. Questo è in netto contrasto con alcune delle webapp che ho usato che hanno molte più Javascript e funzionalità ma funzionano in modo molto fluido (COGNOS di IBM è uno che mi viene in mente dalla parte superiore della mia testa).

Mi piacerebbe conoscere alcuni dei problemi comuni che non vengono considerati durante lo sviluppo di JS che uccideranno le prestazioni del sito.


Probabilmente lo stesso di ogni altro programma: fare più lavoro del necessario e fare lo stesso lavoro più e più volte, spesso centinaia di volte.

1
@delnan è vero, ma sembra che sia molto più diffuso in JS. Percezione forse?
Nic

1
Sta diventando un po 'passe per parlare di "sito" quando si parla di JavaScript. È ovunque e viene utilizzato per tutto in questi giorni.
Adam Crossland,

@Adam Crossland hai perfettamente ragione: in quello stesso caso penso di aver aiutato uno sviluppatore con un'app nativa che si basava fortemente anche su jQuery.
Nic

1
Non è esattamente una risposta alla tua domanda, quindi faccio un commento: ho sperimentato situazioni in cui JavaScript faceva molto rendering, ed era in realtà il motore di rendering del browser che consumava i secondi. Pertanto, per gestire un collo di bottiglia delle prestazioni, vorrei prima cercare operazioni di rendering non necessarie.
user281377

Risposte:


8

Un killer delle prestazioni comune sta chiamando .lengthun HTMLCollection all'interno di un forloop:

function foo(collection) {
    for (var index = 0; index < collection.length; index++) {
        // do something awesome here
    }
}

Tale anti-pattern fa sì che la dimensione della raccolta venga calcolata ad ogni passaggio attraverso il ciclo. L'approccio migliore è calcolare la lunghezza all'esterno del loop:

function foo(collection) {
    var collectionLen = collection.length;
    for (var index = 0; index < collectionLen; index++) {
        // do something awesome here
    }
}

3
Dipende dal browser. Prendi questo benchmark come esempio: in FF 5, quello "normale" funziona praticamente nello stesso momento della versione "ottimizzata". E anche in browser molto vecchi e lenti, qualcosa del genere probabilmente non sarà un collo di bottiglia se JS in realtà fa qualcosa di interessante con gli elementi.

1
Hmm! Forse i compilatori JIT altamente ottimizzanti di oggi stanno rendendo obsoleto questo pizzico di saggezza.
Adam Crossland,

4
Non sono un vero esperto qui, ma dalle specifiche ECMA sembra che la lunghezza sia solo una proprietà dell'oggetto array. Quindi chiamarlo restituisce semplicemente valore invece di contare tutti gli elementi. Non ho idea se tutte le implementazioni seguono le specifiche, ma se lo fanno, il tuo codice non migliora affatto le prestazioni.
Jacek Prucia,

4
@JacekPrucia Ha detto che la raccolta , non l' array - di solito, nel vero codice, ciò significherebbe un elenco di elementi DOM restituiti da funzioni come document.getElementsByTagName. La funzione restituisce un live nodeListche ricalcola la sua lunghezza ogni volta che .lengthsi accede alla proprietà.
Yi Jiang,

2
Il benchmark @JacekPrucia è un miglioramento delle prestazioni. La ricerca della proprietà non è economica.
Raynos,

4

No, il problema non proviene da JS utilizzato come sostituzione del flash. Se non ne sei convinto, documentati su ActionScript: è molto vicino a JS.

Come killer delle prestazioni, puoi trovare diverse cattive pratiche:

  • Collega il gestore eventi su eventi continui, come scorrere, spostare il mouse o cose simili. Questo ha 2 svantaggi: se l'evento non viene attivato abbastanza, l'applicazione non sarà reattiva. Se viene attivato troppo, avrai un carico di CPU enorme per niente.
  • Effettuare chiamate AJAX sincrone. Javascript non è multithread, quindi, quando una parte di JS è in attesa di qualcosa, l'applicazione viene bloccata. È meglio utilizzare le chiamate AJAX asincrone e allo stesso modo utilizzare setTimeout / setInterval per dividere una lunga fase di calcolo e mantenere reattiva l'applicazione.
  • Elevata complessità dell'algoritmo come in qualsiasi altra lingua.

Ho visto più di alcune app tentare di ruotare, semplificare o animare le immagini del browser completo e fallire miseramente nel processo - ecco da dove deriva il commento di sostituzione di Flash :)
Nic

Poiché la prima A in AJAX è asincrona, tecnicamente non è AJAX se è sincrona, ma il tuo punto è ancora valido.
Karl Bielefeldt,

Sì giusto, non è strettamente AJAX. Ma comunque, questo deve essere evitato: D
deadalnix,

3

Ho dato un feedback su un sito Web che utilizzava JavaScript (jQuery) per la sua interazione e l'interfaccia utente: erano animazioni e manipolazioni abbastanza semplici, ma le prestazioni su un computer decente erano orribili.

L'unico problema più grande con le prestazioni è l'utilizzo di astrazioni di alto livello (come jQuery) senza comprendere il modello DOM sottostante e il modello di animazione CSS3 (o canvas, o svg).

Se non sai come farlo senza le astrazioni, allora hai una conoscenza zero assoluta di quali tecniche sono veloci o lente.

Scopri JavaScript, impara il DOM. Una volta che conosci quei due e sai cosa fanno le tue astrazioni sotto il cofano, puoi usarle in modo efficiente. Naturalmente la maggior parte delle volte ti rendi conto che l'astrazione è rallentare e farlo manualmente senza una libreria.


1

Il bello e lo svantaggio di Javascript è che è estremamente flessibile. Detto questo, in realtà ti consente di fare cose che probabilmente non dovresti fare in molti casi.

Dalle recensioni di codice di cui ho fatto parte, le principali preoccupazioni tendono ad essere correlate al rendering CSS. Per i nuovi sviluppatori JS, tendiamo a vedere troppe variabili utilizzate nell'ambito globale.

Inoltre, chiusure improprie possono spesso causare perdite di memoria. Tuttavia, la maggior parte dei moderni framework Javascript previene questo tipo di problemi purché il codice segua il framework.


0

Ecco un breve link che ho trovato circa un anno fa sulla scrittura di un codice jquery migliore: http://net.tutsplus.com/tutorials/javascript-ajax/10-ways-to-instantly-increase-your-jquery-performance /

Una cosa che ho appena trovato in un codice di colleghi che stava uccidendo le prestazioni era la memorizzazione nella cache dei dati che non avevano bisogno di essere memorizzati nella cache.

Esempio:

var table = $("#data").dataTable(.....);

DataTables è un plug-in jQuery che utilizziamo per creare belle griglie. Ad ogni modo, la tabella conteneva quasi 5k righe, applicando il plug-in DataTables e quindi salvandolo nella variabile tabella, in realtà sia FireFox che IE avvertivano che uno script stava impiegando troppo tempo. Morale della storia, memorizza nella cache i dati solo se necessario.


1
Sembra che DataTables sia un plugin davvero inefficiente / scarso piuttosto che un problema con la memorizzazione nella cache. 5k non è niente.
Raynos,

@Raynos: ha detto 5k righe , non 5 kilobyte di dati. Una "fila" potrebbe essere una cosa molto grande.
Chris Farmer,

@ChrisFarmer Se una "riga" è una cosa molto grande, allora hai un problema diverso .
Raynos,

-1

Da quello che ho sentito, i forloop sono più veloci dal punto di vista computazionale di quelli di jQuery $.each().


3
È una risposta scherzosa?
Raynos,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.