Fornisce CSS e JavaScript compressi da Amazon CloudFront tramite S3


194

Ho cercato modi per velocizzare il caricamento del mio sito e un modo che mi piacerebbe esplorare è quello di utilizzare maggiormente Cloudfront.

Poiché Cloudfront non era originariamente progettato come CDN di origine personalizzata e poiché non supportava il gzipping, finora lo ho usato per ospitare tutte le mie immagini, a cui fa riferimento il loro nome Cloudfront nel mio codice del sito e ottimizzato con -testazioni del futuro.

I file CSS e javascript, d'altra parte, sono ospitati sul mio server, perché fino ad ora avevo l'impressione che non potessero essere serviti gzip da Cloudfront e che il guadagno dal gzip (circa il 75%) supera quello dall'uso di una CDN (circa il 50%): Amazon S3 (e quindi Cloudfront) non supportava la pubblicazione di contenuti gzip in modo standard utilizzando l'intestazione HTTP Accept-Encoding che viene inviata dai browser per indicare il loro supporto per la compressione gzip e quindi non sono stati in grado di Gzip e servire componenti al volo.

Quindi avevo l'impressione, fino ad ora, che si dovesse scegliere tra due alternative:

  1. spostare tutte le risorse su Amazon CloudFront e dimenticare GZipping;

  2. mantenere i componenti ospitati autonomamente e configurare il nostro server per rilevare le richieste in arrivo ed eseguire GZipping al volo nel modo appropriato, che è quello che ho scelto di fare finora.

Ci sono state soluzioni alternative per risolvere questo problema, ma essenzialmente questi non hanno funzionato . [ link ].

Ora, sembra che Amazon Cloudfront supporti l'origine personalizzata e che ora sia possibile utilizzare il metodo HTTP Accept-Encoding standard per la pubblicazione di contenuti compressi se si utilizza un collegamento [ Origin ] personalizzato.

Finora non sono stato in grado di implementare la nuova funzionalità sul mio server. Il post sul blog che ho collegato sopra, che è l'unico che ho trovato in dettaglio la modifica, sembra implicare che puoi abilitare il gzipping (soluzioni alternative della barra, che non voglio usare), se opti per l'origine personalizzata, che Preferirei di no: trovo più semplice ospitare i file corrispondenti sul mio server Cloudfront e collegarli ad essi da lì. Nonostante abbia letto attentamente la documentazione, non so:

  • se la nuova funzionalità significa che i file devono essere ospitati sul mio server di dominio tramite origine personalizzata e, in tal caso, quale impostazione del codice raggiungerà questo obiettivo;

  • come configurare le intestazioni css e javascript per assicurarsi che vengano servite gzip da Cloudfront.

Risposte:


202

AGGIORNAMENTO: Amazon ora supporta la compressione gzip, quindi non è più necessario. Annuncio di Amazon

Risposta originale:

La risposta è di decomprimere i file CSS e JavaScript. Sì, avete letto bene.

gzip -9 production.min.css

Questo produrrà production.min.css.gz. Rimuovere .gz, caricare su S3 (o qualunque altro server di origine in uso) e impostare esplicitamente l' Content-Encodingintestazione per il file gzip.

Non è un gzip al volo, ma potresti facilmente includerlo negli script di compilazione / distribuzione. I vantaggi sono:

  1. Non richiede CPU per Apache per decomprimere il contenuto quando viene richiesto il file.
  2. I file vengono compressi con il gzip al massimo livello di compressione (supponendo gzip -9).
  3. Stai servendo il file da una CDN.

Supponendo che i tuoi file CSS / JavaScript siano (a) minimizzati e (b) abbastanza grandi da giustificare la CPU richiesta per decomprimere sul computer dell'utente, puoi ottenere significativi miglioramenti delle prestazioni qui.

Ricorda: se apporti una modifica a un file memorizzato nella cache in CloudFront, assicurati di invalidare la cache dopo aver apportato questo tipo di modifica.


37
Dopo aver letto il tuo link, devo dire che l'autore del blog non è informato. "Tuttavia, se l'utente ha un browser che non supporta la codifica gzip, i fogli di stile zippati e i javascript del tuo sito semplicemente non funzioneranno per quell'utente." Questo browser sarebbe probabilmente troppo vecchio per eseguire comunque i tuoi fogli di stile e file di script. Questi utenti rappresentano una frazione del percento.
Skyler Johnson,

3
AGGIORNAMENTO: l'ho risolto. Il motivo per cui non veniva visualizzato era che avevo dimenticato di impostare Content-Type su text / css. Se lo fai, stai bene, anche se per qualche motivo sembra che non puoi aggiungere un'intestazione "Accept-Encoding: Vary" in S3 (che aiuterebbe con la valutazione di Google Speed) per i motivi descritti qui: [link ]. Inoltre, ho impostato il controllo della cache per memorizzare nella cache l'asset, ma non sembra memorizzarlo nella cache ...
Donald Jenkins

32
Ho appena trovato questo tramite Google e mi dispiace dover dire che non è un buon consiglio. Mentre <1% dei browser desktop non è in grado di gestire i contenuti compressi con zip, molti browser mobili non possono farlo. Quanti dipendono dal pubblico target che stai guardando; ma la maggior parte dei vecchi Nokia S40 hanno ad esempio una compressione con gzip difettosa. Il modo corretto è un "Origine personalizzata", che punta a un server Web Apache / IIS che esegue la compressione del contenuto e serve le intestazioni HTTP appropriate. Ecco un post sul blog che ne descrive l'essenza: nomitor.com/blog/2010/11/10/…
Jesper M

14
Com'è la situazione ora, all'inizio del 2015? I link pubblicati da @JesperMortensen e Simon Peck sono ancora rilevanti?
ItalyPaleAle

5
Amazon ha annunciato il supporto per la compressione gzip nel dicembre del 2015, quindi questo è irrilevante basta caricare il file di base e funzionerà. aws.amazon.com/blogs/aws/…
Sean,

15

La mia risposta è un decollo su questo: http://blog.kenweiner.com/2009/08/serving-gzipped-javascript-files-from.html

Costruendo la risposta di skyler puoi caricare una versione gzip e non gzip di css e js. Fai attenzione a nominare e testare in Safari. Perché Safari non gestirà .css.gz.js.gzfile.

site.jse site.js.jgze site.csse site.gz.css (dovrai impostare l' content-encodingintestazione sul tipo MIME corretto per farli funzionare correttamente)

Quindi nella tua pagina inserisci.

<script type="text/javascript">var sr_gzipEnabled = false;</script> 
<script type="text/javascript" src="http://d2ft4b0ve1aur1.cloudfront.net/js-050/sr.gzipcheck.js.jgz"></script> 

<noscript> 
  <link type="text/css" rel="stylesheet" href="http://d2ft4b0ve1aur1.cloudfront.net/css-050/sr-br-min.css">
</noscript> 
<script type="text/javascript"> 
(function () {
    var sr_css_file = 'http://d2ft4b0ve1aur1.cloudfront.net/css-050/sr-br-min.css';
    if (sr_gzipEnabled) {
      sr_css_file = 'http://d2ft4b0ve1aur1.cloudfront.net/css-050/sr-br-min.css.gz';
    }

    var head = document.getElementsByTagName("head")[0];
    if (head) {
        var scriptStyles = document.createElement("link");
        scriptStyles.rel = "stylesheet";
        scriptStyles.type = "text/css";
        scriptStyles.href = sr_css_file;
        head.appendChild(scriptStyles);
        //alert('adding css to header:'+sr_css_file);
     }
}());
</script> 

gzipcheck.js.jgz è solo sr_gzipEnabled = true; Questo test per assicurarsi che il browser sia in grado di gestire il codice gzip e fornire un backup se non è possibile.

Quindi fai qualcosa di simile nel piè di pagina assumendo che tutti i tuoi js siano in un file e possano andare nel piè di pagina.

<div id="sr_js"></div> 
<script type="text/javascript"> 
(function () {
    var sr_js_file = 'http://d2ft4b0ve1aur1.cloudfront.net/js-050/sr-br-min.js';
    if (sr_gzipEnabled) {
       sr_js_file = 'http://d2ft4b0ve1aur1.cloudfront.net/js-050/sr-br-min.js.jgz';
    }
    var sr_script_tag = document.getElementById("sr_js");         
    if (sr_script_tag) {
    var scriptStyles = document.createElement("script");
    scriptStyles.type = "text/javascript";
    scriptStyles.src = sr_js_file;
    sr_script_tag.appendChild(scriptStyles);
    //alert('adding js to footer:'+sr_js_file);
    }
}());
</script> 

AGGIORNAMENTO: Amazon ora supporta la compressione gzip. Annuncio, quindi non è più necessario. Annuncio di Amazon


grazie mille per quel suggerimento. Se ti capisco correttamente, stai affrontando il caso in cui il browser dell'utente non è in grado di leggere il file gzipped, che può ancora verificarsi sebbene riguardi una percentuale abbastanza piccola di browser al giorno d'oggi. Un possibile svantaggio di questa soluzione, se fai riferimento al link che ho pubblicato nella mia domanda [link ] è che significa che non puoi memorizzare nella cache la tua pagina, poiché funzionerà solo se il tuo codice viene eseguito in modo dinamico ogni volta che un utente carica la pagina (che ovviamente è la mia).
Donald Jenkins,

@DonaldJenkins Penso che il js sarà ancora memorizzato nella cache. Quando si crea il tag di script in js snip, è ancora necessario chiamare js e credo che se fosse nella cache il browser lo userebbe da lì.
Sean,

2
La pagina di test blog.kosny.com/testpages/safari-gz indica che l'avviso "Prestare attenzione alla denominazione e al test in Safari. Perché Safari non gestirà css.gz o js.gz" non è aggiornato. In Safari 7 su Mavericks e in Safari su iOS 7, funzionano sia css.gz che js.gz. Non so quando si è verificato questo cambiamento, sto solo testando con i dispositivi che ho.
Garyrob,

14

Cloudfront supporta il gzipping.

Cloudfront si connette al tuo server tramite HTTP 1.0. Per impostazione predefinita alcuni server web, incluso nginx, non servono contenuti compressi con gzip alle connessioni HTTP 1.0, ma puoi dirlo facendo aggiungendo:

gzip_http_version 1.0

alla tua configurazione nginx. La configurazione equivalente potrebbe essere impostata per qualsiasi server Web in uso.

Ciò ha un effetto collaterale nel rendere le connessioni keep-alive non funzionanti per le connessioni HTTP 1.0, ma poiché i vantaggi della compressione sono enormi, vale sicuramente la pena fare un salto.

Tratto da http://www.cdnplanet.com/blog/gzip-nginx-cloudfront/

modificare

La pubblicazione di contenuti compressi al volo tramite Amazon Cloud Front è pericolosa e probabilmente non dovrebbe essere eseguita. Fondamentalmente se il tuo server web sta comprimendo il contenuto, non imposterà una lunghezza del contenuto e invierà invece i dati come grossi.

Se la connessione tra Cloudfront e il server viene interrotta e interrotta prematuramente, Cloudfront memorizza comunque nella cache il risultato parziale e lo utilizza come versione cache fino alla scadenza.

La risposta accettata di comprimerlo prima su disco e quindi di servire la versione con gzip è un'idea migliore in quanto Nginx sarà in grado di impostare l'intestazione Content-Length e Cloudfront eliminerà le versioni troncate.


5
-1, questa risposta non ha nulla a che fare con la domanda. Nginx! = S3 e Cloudfront
Jonathan

@Danack, hai riscontrato molti problemi con la memorizzazione nella cache di file recuperati per metà a causa di questo problema? Sto cercando di capire quanto sia stato un problema per te in pratica.
più elegante

1
@poshest È successo. Il servizio con gzip è stato molto limitato (poiché gzip è comunque molto veloce sul server), quindi l'ho spento non appena l'ho visto accadere. I dati danneggiati sono un problema molto più grande che avere un "tempo al primo byte" lento di 200 ms nei rari casi in cui il contenuto non esiste già in formato gzip.
Danack,

Se un asset manca di una proprietà Content-Length nell'intestazione ma include Transfer-Encoding: chunked (come spesso accade con gli asset compressi), CloudFront NON memorizzerà nella cache un asset parziale se non riceve un blocco di terminazione. Se mancano entrambe queste proprietà, è possibile che una risorsa incompleta venga memorizzata nella cache. Vedi: docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/…
Cody Duval

5

Di recente abbiamo apportato alcune ottimizzazioni a uSwitch.com per comprimere alcune delle risorse statiche sul nostro sito. Anche se abbiamo configurato un intero proxy nginx per farlo, ho anche messo insieme una piccola app Heroku che esegue il proxy tra CloudFront e S3 per comprimere il contenuto: http://dfl8.co

Dato che gli oggetti S3 accessibili al pubblico sono accessibili tramite una semplice struttura URL, http://dfl8.co utilizza solo la stessa struttura. Vale a dire i seguenti URL sono equivalenti:

http://pingles-example.s3.amazonaws.com/sample.css
http://pingles-example.dfl8.co/sample.css
http://d1a4f3qx63eykc.cloudfront.net/sample.css

5

Ieri Amazon ha annunciato una nuova funzionalità, ora puoi abilitare gzip sulla tua distribuzione.

Funziona con s3 senza aggiungere file .gz, ho provato la nuova funzionalità oggi e funziona benissimo. (è necessario invalidare gli oggetti correnti)

Ulteriori informazioni


0

Puoi configurare CloudFront per comprimere automaticamente file di determinati tipi e servire i file compressi.

Vedi la Guida per gli sviluppatori AWS


Puoi aggiungere ulteriori informazioni sulla tua soluzione (forse un esempio) per renderla una risposta migliore.
Yagami Light,
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.