venerdì 9 dicembre 2011

Al di là di YSlow - Squeeeezing le prestazioni della rete web

Ho avuto un sacco di conversazioni con gente di recente sulle prestazioni web app. Spesso queste conversazioni sono stati in giro l'affermazione che una rete di distribuzione di contenuti (qui avanti indicato come CDN), è qualcosa che è necessario distribuire nelle prime fasi del processo di ottimizzazione di un sito web. Personalmente, vedo una CDN come ultima risorsa, ma è quello che ti rivolgi a quando tutte le altre alternative di ottimizzazione delle prestazioni sono state esaurite e avete bisogno di guadagnarsi da quel po 'di latenza ultimi spostando il contenuto più vicino al pubblico. Non è un sostituto per l'ottimizzazione buon sito web, è un miglioramento .
Uno dei problemi principali con un CDN è semplicemente questo: le persone hanno ancora connessioni merda. Non importa se riesco a mettere il contenuto nella stessa città, come il pubblico, se sono in un luogo dove "banda larga" è un 1Mb connessione o anche se hai un super-veloce, ma il servizio di 3 bambini sono tutte allo stesso tempo scaricare torrent, hai un problema. Come ben ottimizzato il sito è ora conta molto di più di quanto vicino il contenuto è a voi.
Il punto che sto facendo è questa: contenuto ben ottimizzato è re. Se si può ottenere che il video in basso da 2Mb / s fino a 500Kb / s (suona come un sacco, ma ho di frequentevedere questo tipo di scenario), o drasticamente ridurre drasticamente il numero di richieste HTTP e la dimensione del contenuto di una pagina web, si sta andando a cogliere quei benefici in qualsiasi circostanza. E 'qui che bisogna partire; ottenere questo primo diritto perché è più veloce, più economico per aggiungere le prestazioni.
Quindi mi ha fatto pensare: quanti miglioramenti possono essere fatti su un sito già ben ottimizzato, Voglio dire, uno che segna molto bene contro parametri di valutazione delle prestazioni attuali? Quanto più velocemente si può andare senza spendere dollari su un CDN?Si scopre che ci sono grandi guadagni da fare molto velocemente - e costa solo un po 'di tempo di sviluppo.

Stabilire una base

Questo non è uno di quei "Ehi, guarda questo miseramente spettacolo, siti poco ottimizzato e quanto di meglio ho appena fatto" i messaggi. No, si tratta di fare un sito ben ottimizzato e rendendolo, così, più ottimizzato.
All'inizio di questa settimana ho lanciato ASafaWeb , un ASP.NET MVC 3 app per l'analisi dinamica di vulnerabilità di sicurezza relativi a configurazione. NET siti web. Ho un idea abbastanza precisa di quello che serve per fare un sito web veloce e dal primo giorno sono stato in grado di applicare i principi fondamentali, tanto che YSlow già dato il sito di un verde molto grande "A" senza nemmeno provarci:
YSlow relazione ASafaWeb prima optimisaiton
Questo di per sé è stato un eccellente risultato, soprattutto considerando che spesso coinvolto nel guardare poveri luoghi dello spettacolo e vengono direttamente dalla scatola con una B, C o anche classe D (quelle 19 domande separate. Js non ha aiutato) . Ma questo non lo rendono perfetto non, di gran lunga. In realtà non vi è un guadagno significativo per essere in cima a questo. Ma prima di entrare in questo, cerchiamo di stabilire una linea di base.
Ecco cosa sta succedendo in prima pagina:
Prima pagina del ASafaWeb
E secondo Fiddler , ecco come è tutto l'essere caricato:
Violinista traccia di ASafaWeb prima dell'ottimizzazione
Ci sono poche cose da notare qui:
  1. Tutto diverso da quello delle immagini sta già utilizzando la compressione HTTP (le bitmap sono già ben ottimizzati). Mentre la prima risposta che mostra un corpo di 2.237 byte, in realtà è più del doppio che nella prima (5237).
  2. Richieste 3, 4 e 5 provengono tutti dal CDN Microsoft e servire i file jQuery (anche compresso).
  3. Richieste di 7 e 14 sono Google Analytics.
Per capire cosa questo assomiglia in termini di sequenza di richieste e le dipendenze, ecco la linea temporale:
Timeline di ASafaWeb prima dell'ottimizzazione
Che cosa è un po 'interessante di questo è che il file Site.css - che è 2.900 byte - è di circa sei volte di più a caricare il file di jQuery primo che è 15 volte più grande. Questo è il potere del CDN e senza dissacrante mia affermazione proprio nel paragrafo d'apertura di questo post, una CDN può essere molto utile al momento giusto . Facciamo scarico tutte quelle strade di ottimizzazione per primo.
Ora i miei risultati non saranno gli stessi di tutti gli altri. Sono a Sydney e hosting ASafaWeb su AppHarbor che pone i contenuti negli Stati Uniti piuttosto che in Australia. Questo dà un'idea della differenza di prestazioni tra le massicce richieste ASafaWeb e quelli del CDN di Microsoft (che presumo dalle figure, ha una presenza locale).
In sintesi, significa tutto questo:
Riassunto delle richieste ASafaWeb prima dell'ottimizzazione
Il bit di cui sopra è importante la durata della sequenza, la pagina si carica completamente in 2,34 secondi. Caricarlo di nuovo e ci sarà un risultato diverso, ma la mia connessione è abbastanza stabile per dare un buon livello di coerenza. E 'questa durata che si vuole scendere.
Ancora una cosa: tutto questo è stato fatto con Chrome. Altri browser potrebbero richieste sequenza in modo leggermente diverso o sostenere un diverso numero di connessioni simultanee. Indipendentemente da ciò, le ottimizzazioni a venire potranno beneficiare tutti i browser. Un sacco.

Andando oltre le nozioni di base

Ci sono quattro cose che ho intenzione di fare che ha unito, farà una differenza significativa per quanto ASafaWeb esegue:
  1. Ridurre il numero di richieste HTTP. Ogni richiesta invia ulteriori byte nell'intestazione della richiesta, riceve ulteriori byte nell'intestazione di risposta e richiede un'altra connessione TCP che sostiene l'ira di latenza di rete. Inoltre, vieta il browser da fare un'altra richiesta se ha raggiunto il numero massimo di connessioni simultanee che può tenere aperto.
  2. Ridurre la dimensione dei contenuti. Posso fare questo riducendo al minimo i file CSS e JavaScript.
  3. Utilizzare un sistema di URI dati . In breve, posto alcuni dati binari in linea nel CSS, piuttosto che fare una richiesta separata di immagine. Questo ci aiuta con il punto 1.
  4. Utilizzare un sprite immagine . Questo pone bitmap multipli nella propria immagine e usa CSS per tritarli e posizionarli. Ancora una volta, contribuisce con il punto 1.
Ora che ho detto tutto questo, io non ho intenzione di affrontarlo in tutto questo ordine. Sto per iniziare la creazione del folletto, semplicemente perché ci aiuta con alcuni degli obiettivi di cui sopra. Ho iniziato guardando il Sprite ASP.NET & Ottimizzazione quadro immagine . In teoria, questo suona bene. In pratica, ero un po 'deludente.
Fondamentalmente, l'idea è che si tira il quadro in da NuGet, whack le immagini nella cartella appena creata "App_Sprite" poi riferimento al file appena creato CSS e singole immagini attraverso alcune sintassi Razor funky. Tutto bene in teoria.
Ma i problemi che ho avuto sono state numerose e di più, perché volevo un controllo molto preciso di ogni altra cosa. In primo luogo, il modello predefinito è quello di generare un file ad alta compatibilità con CSS che utilizza lo schema URI dati (ossia in grande con un sacco di dati binari in linea e supporto limitato per i browser più recenti ), e un file di compatibilità bassa che usa solo il tuo sprite classico ( compatibilità molto ampia). Il problema è che volevo un po 'di entrambi.
Il problema inizia con la ripetizione immagini di sfondo. Sprites lavorare sul concetto di esplicita scelta di una posizione nell'immagine poi tritare X pixel pixel di larghezza e Y alto.Non si può poi prendere questa fetta e ripeterla in una data direzione a meno che l'intero sprite è esattamente la stessa dimensione come la direzione si sta ripetendo in . Ad esempio, se avete un po 'di ripetere in orizzontale sfondo, è possibile effettuare si 1px di larghezza e li pila l'uno sopra l'altro. Tuttavia, gettare nel più ampio niente e sei fuori di fortuna piatto a meno che non si estendono alla larghezza dello sprite intero. E tu sei bloccato, se si desidera uno di loro a ripetere verticalmente.
ASafaWeb ha due immagini si ripetono orizzontalmente, uno fa l'ombra sotto la barra di navigazione e l'altro fa la linea a strisce:
Ripetono orizzontalmente immagini su ASafaWeb
Sono entrambi 1 pixel di larghezza (senza bisogno di più), e 8 pixel di altezza e 3 rispettivamente. Ha anche un 1 di 1 pixel semi-trasparenti PNG che ripete in entrambe le direzioni (a volte l'elemento è in ha un bordo che io non voglio la trasparenza applicata in modo trasparente CSS è out):
Semi sfondo trasparente su ASafaWeb
Sono tutti piccoli e sono tutti adatti per l'inclusione in uno sprite insieme, soprattutto una volta che si aggiunge altre immagini.
A proposito, ci sono 5 altre immagini che appaiono come due tag <img> classico sulla pagina o come sfondi su altri elementi via CSS. Lo sprite di cui sopra e l'ottimizzazione quadro immagine funziona bene per i tag immagine, ma non ti aiuta con le immagini di sfondo nel CSS, almeno non automaticamente.
Ma la cosa che mi ha ostacolato è questa:
Sprite che è significativamente più grande le immagini sorgenti combinate
Quello che vedete qui sono le cinque immagini che si desidera creare uno sprite da. Sono evidenziate e mostrano una dimensione totale di 26.4KB. Ora guardate il file "sprite0.png" - questo è quello creato dal framework di ottimizzazione. Problema è che è del 33% maggiorerispetto ai file originali combinati. Sì, lo so, è un minor numero di richieste HTTP ed a conti fatti, sarebbe quasi certamente più veloce, ma ancora, sembra proprio sbagliato . Certo le immagini sono state tutte ben ottimizzato per Photoshop per cominciare, ma ancora, in crescita di un terzo? E questo quadro è stato uno dei migliori risultati in termini di dimensioni dell'immagine finale, ho provato una serie di altri ei risultati sono stati anche peggio.
Ed è un po 'sbagliato, perché se poi prendete questa immagine e Smush.it , si restringe piuttosto rapidamente:
Smush.it riducendo le dimensioni del file sprite del 15%
Ok, è ancora maggiore rispetto agli originali, ma quando si parla di questo livello di ottimizzazione, mi aspettavo che tipo di essere meglio ottimizzato per cominciare. Ora non posso vedere se l'ottimizzazione è stata ottenuta estraendo qualità, ai miei occhi almeno (e lo faccio tendono ad essere piuttosto pedante), non c'è nessuna perdita visibile di qualità.
Comunque, il punto di tutto questo è che il quadro di ottimizzazione ha contribuito a creare alcuni schemi dati URI, un folletto che ho poi ulteriormente ottimizzati e, naturalmente, tutte le richieste CSS per posizionare correttamente e display che sprite. Una volta che è stato fatto, ho solo bisogno di mettere mano insieme le cose nel modo che volevo.
Un po 'di tentativi ed errori portano a questo:
  1. Utilizzare schemi di URI dati per le immagini di sfondo ripetendo. Sono piccoli, facili da cadere nel già esistenti CSS e non essenziali, se un cliente non può caricare.
  2. Generare lo sprite per i restanti piccoli immagini PNG e manualmente utilizzare gli stili generato da questo nel mio attuale CSS (cioè copia e incolla).
  3. Smush lo sprite dal passaggio precedente per farlo fino ad una dimensione ragionevole.
  4. Eventuali GIF animate (ho un paio di "carico" delle sequenze), o più grande file PNG (lo sfondo della pagina è di 280 x 814 pixel), rimangono come file standalone.
Questo è tutto bello ma un altro che possiamo fare per ridurre al minimo le richieste è quella di dare uno sguardo alle due file CSS. Un paio di mesi fa ho parlato con normalize.css per stabilire una base coerente comportamentale tutti i browser. Ho mantenuto questo file separato perché volevo aggiornare facilmente in futuro. Il problema è che questo crea un'ulteriore richiesta HTTP. Bottom line: ho combinato con il file CSS esistente con il contenuto di normalizzare la cima. Fine lo stesso risultato, una minore richiesta HTTP.
Poi c'è la minimizzazione. L'idea è che i CSS e JavaScript sono notoriamente inefficienti. Tutti coloro che non torna caldo e al sicuro e rientranze grande lavoro per noi umani ma sono spreco di spazio sulla rete, il browser non si preoccupa per loro un po '. Stessa cosa con le variabili JavaScript; tutta la logica di codice pulito al mondo in termini di denominazione non significa nulla per il browser e le viti solo con l'utilizzo della larghezza di banda.
Ci sono un sacco di minimisers diverse là fuori, ma Yahoo YUI Compressor è costantemente valutato come uno dei migliori. Lasciatemi dimostrare, ecco le prime righe di ASafaWeb suo file js:.
funzione PostInvalidViewState (percorso, target) {
     var form = document.createElement ( "forma" );
    form.setAttribute ( "metodo" , "POST" );
    form.setAttribute ( "azione" , percorso);
E qui è ancora una volta, dopo YUI Compressor ha avuto la sua strada con esso:
function PostInvalidViewState(d,c){var b=document.createElement
("form");b.setAttribute("method","POST");b.setAttribute("action",d);
Non torna né più, né il rientro di più e anche i parametri del metodo più la variabile "forma" sono stati tutti convertiti in caratteri singoli. Leggibilità incubo, ma funzionalmente identici.
Accordo simile con il CSS. Ecco l'originale:
corpo
 {
   background-color : # 1F1E1E ;
   carattere : 0,8 em Verdana, sans-serif ;
   margine : 0 ;
   padding : 0 ;
   color : # 9A9898 ;
}
E ora la versione minified:
corpo { background-color : # 1f1e1e ; carattere : 0,8 em 
Verdana, sans-serif ; margine : 0 ; padding : 0 ; color : # 9a9898 }
Anche gli spazi tra attributo e valore se ne sono andati: sono letteralmente sprecato spazio (ok, brutto gioco di parole!)
Minimizzazione è grande, ma devi tenere gli originali, se vi capitasse di voler lavorare sui file di nuovo. Ho appena creato un piccolo file batch per fare tutto il lavoro sopra (combinare i CSS poi minimizzare insieme al JS), e inserire un ". Min" dopo il nome del file.
Nel caso dei CSS, ecco la linea di fondo:
immagine
Prendendo la normalize.css, whacking l'alto la parte superiore del Site.css poi minifying tutto e salvarlo come Site.min.css ha più che dimezzato le dimensioni totali ! Non solo, ma abbiamo anche una richiesta HTTP meno. Giorni felici.

Nuova misurazione

Tutti i conti sopra a nulla se non possiamo fare guadagni misurabili. Ecco il risultato finale:
Richieste violinista dopo l'ottimizzazione
L'originale 19 domande: ora 12. Questo è un buon inizio. Ma vediamo il dettaglio:
Dettaglio violinista di miglioramenti delle prestazioni dopo l'ottimizzazione
E 'più facile quando si vede un confronto diretto dei bit di veramente importante:
 
Prima
Dopo
Cambiare
Richieste
19
12
-37%
Byte inviati
15.818
9217
-42%
Byte ricevuti
121.368
119.544
-1,5%
Durata (secondi)
2,34
1,86
-20%
Noi sappiamo perché le richieste sono diminuite ei byte inviati gocce per motivi connessi; ogni richiesta include i dati di intestazione come il browser, la tua scelta (parlato) la lingua ed i cookie il sito è impostato. Ridurre le richieste, ridurre i dati inviati.
Byte ricevuti a malapena i cambiamenti e la risposta perché questo è nella inefficienza dello sprite. Anche dopo lo smushing, ha aggiunto byte che abbiamo appena superato attraverso la minimizzazione. E 'ancora una netta riduzione in byte, ma la riduzione delle richieste è stato ancora più importante.
Ma il grande - l'unica che conta veramente - è la durata preso per tutta la baracca da caricare. 20% di persone - che non è piccolo cambiamento! E ricordate, che è 20% più veloce su un pre-ottimizzate, "A" le prestazioni del sito di qualità!
Questo è un risultato molto piacevole.

Riassunto

Tutto ciò è al di sopra altamente variabile; velocità di rete vanno su e giù, diversi browser si comportano diversamente, c'è ancora tempo di rendering di prendere in considerazione, c'è vita oltre un carico di freddo (niente cache), ecc ecc Ma quando torneremo al contesto ho impostato all'inizio - quella di non pre-ottimizzazione con un CDN - spero che il punto è ormai chiaro. Un sito molto ben ottimizzato, che già implementa la compressione HTTP, le richieste minime, saranno ottimizzate le immagini e utilizza anche un CDN per alcune richieste possonoancora rendere un guadagno del 20% da appena un paio d'ore di ottimizzazione intelligente.
Il CDN è il prossimo passo. Può anche ottenere un altro 20% - o forse solo il 15%, forse 25% - Non lo so. Ma quello che so è che vi costerà un carico perso più di un paio d'ore di tempo di sviluppo. Questo è ormai il regno di aumentare esponenzialmente il tempo e dollari per lo stesso guadagno e questo è dove si vuole essere al fine di ottimizzazione la vostra gente, non all'inizio.
Oh, e solo nel caso in cui non siete convinti del valore di questo esercizio o ti sei dimenticato come ci si sente ad avere una connessione lenta miseramente (o sei troppo giovane per aver vissuto la gioia di internet più di 56kbps), provare a impostare Fiddler per simulare la velocità del modem e navigare in giro per un po '. ASafaWeb ora completamente carica in 14 secondi - non sarà possibile ottenere che su altri siti troppi!

Nessun commento:

Posta un commento