Melayani gzip CSS dan JavaScript dari Amazon CloudFront via S3

194

Saya telah mencari cara untuk membuat situs saya memuat lebih cepat dan satu cara yang ingin saya jelajahi adalah memanfaatkan Cloudfront dengan lebih baik.

Karena Cloudfront pada awalnya tidak dirancang sebagai CDN asal-kustom dan karena itu tidak mendukung gzipping, sejauh ini saya menggunakannya untuk meng-host semua gambar saya, yang dirujuk oleh cname Cloudfront mereka dalam kode situs saya, dan dioptimalkan dengan jauh header masa depan.

Sebaliknya, file CSS dan javascript di-host di server saya sendiri, karena sampai sekarang saya mendapat kesan bahwa mereka tidak dapat dilayani dengan gzip dari Cloudfront, dan bahwa keuntungan dari gzip (sekitar 75 persen) lebih besar daripada dari menggunakan CDN (sekitar 50 persen): Amazon S3 (dan dengan demikian Cloudfront) tidak mendukung penyajian konten yang di-gzip dengan cara standar dengan menggunakan header HTTP-Encoding-Terima yang dikirim oleh browser untuk menunjukkan dukungan mereka untuk kompresi gzip, dan jadi mereka tidak dapat Gzip dan melayani komponen dengan cepat.

Jadi saya mendapat kesan, sampai sekarang, bahwa seseorang harus memilih antara dua alternatif:

  1. pindahkan semua aset ke Amazon CloudFront dan lupakan tentang GZipping;

  2. menjaga komponen di-host-sendiri dan mengonfigurasi server kami untuk mendeteksi permintaan yang masuk dan melakukan GZipping on-the-fly yang sesuai, yang merupakan apa yang saya pilih untuk dilakukan sejauh ini.

Ada yang workarounds untuk memecahkan masalah ini, tapi pada dasarnya ini tidak bekerja . [ tautan ].

Sekarang, tampaknya Amazon Cloudfront mendukung asal kustom, dan sekarang mungkin untuk menggunakan metode Pengkodean Terima HTTP standar untuk menyajikan konten yang di-gzip jika Anda menggunakan tautan Custom Origin [ link ].

Sejauh ini saya belum dapat mengimplementasikan fitur baru di server saya. Posting blog yang saya tautkan di atas, yang merupakan satu-satunya yang saya temukan yang merinci perubahannya, tampaknya menyiratkan bahwa Anda hanya dapat mengaktifkan gzipping (bilah solusi, yang tidak ingin saya gunakan), jika Anda memilih asal kustom, yang Saya lebih suka tidak: Saya merasa lebih mudah untuk meng-host fil yang merespons di server Cloudfront saya, dan menautkannya ke sana. Meskipun membaca dokumentasi dengan cermat, saya tidak tahu:

  • apakah fitur baru berarti file harus di-host di server domain saya sendiri melalui asal kustom, dan jika demikian, pengaturan kode apa yang akan mencapai ini;

  • cara mengkonfigurasi header css dan javascript untuk memastikan mereka dilayani di-gzip dari Cloudfront.

Donald Jenkins
sumber

Jawaban:

202

PEMBARUAN: Amazon sekarang mendukung kompresi gzip, jadi ini tidak lagi diperlukan. Pengumuman Amazon

Jawaban asli:

Jawabannya adalah gzip file CSS dan JavaScript. Ya, Anda membacanya dengan benar.

gzip -9 production.min.css

Ini akan menghasilkan production.min.css.gz. Hapus .gz, unggah ke S3 (atau server asal apa pun yang Anda gunakan) dan atur Content-Encodingtajuk untuk file secara eksplisit gzip.

Ini bukan gzipping on-the-fly, tetapi Anda bisa dengan mudah membungkusnya dengan skrip build / deployment Anda. Keuntungannya adalah:

  1. Tidak memerlukan CPU untuk Apache untuk gzip konten ketika file diminta.
  2. File-file tersebut di-gzip pada level kompresi tertinggi (dengan asumsi gzip -9).
  3. Anda sedang melayani file dari CDN.

Dengan asumsi bahwa file CSS / JavaScript Anda (a) diperkecil dan (b) cukup besar untuk membenarkan CPU yang diperlukan untuk melakukan dekompresi pada mesin pengguna, Anda bisa mendapatkan keuntungan kinerja yang signifikan di sini.

Ingat saja: Jika Anda membuat perubahan pada file yang di-cache di CloudFront, pastikan Anda membatalkan cache setelah membuat jenis perubahan ini.

Skyler Johnson
sumber
37
Setelah membaca tautan Anda, saya harus mengatakan bahwa penulis blog tidak mendapat informasi. "Namun, jika pengguna memiliki peramban yang tidak mendukung penyandian gzip, lembar gaya dan javascript zip situs Anda tidak akan berfungsi untuk pengguna itu." Peramban ini sepertinya terlalu tua untuk menjalankan file stylesheet dan skrip Anda. Pengguna ini hanya sebagian kecil dari persen.
Skyler Johnson
3
PEMBARUAN: Saya berhasil. Alasan tidak ditampilkan adalah karena saya lupa mengatur Content-Type menjadi teks / css. Jika Anda melakukannya, Anda baik-baik saja, meskipun karena alasan tertentu sepertinya Anda tidak dapat menambahkan header "Terima-Pengodean: Bervariasi" dalam S3 (yang akan membantu dengan peringkat Google Speed) karena alasan yang dijelaskan di sini: [tautan ] Juga, saya mengatur kontrol-Cache ke cache aset, tetapi tampaknya tidak akan caching itu ...
Donald Jenkins
32
Baru saja menemukan ini melalui Google, dan saya menyesal harus mengatakan ini bukan saran yang bagus. Meskipun <1% browser desktop tidak dapat menangani konten yang di-gzip, cukup banyak browser seluler yang tidak bisa. Berapa banyak tergantung pada target audiens yang Anda lihat; tetapi kebanyakan Nokia S40 yang lebih tua memiliki kompresi buggy gzip misalnya. Cara yang tepat adalah "Custom Origin", yang menunjuk ke server web Apache / IIS yang melakukan kompresi konten dan melayani tajuk HTTP yang tepat. Berikut adalah satu posting blog yang menggambarkan intinya: nomitor.com/blog/2010/11/10/…
Jesper M
14
Bagaimana situasinya sekarang, di awal 2015? Apakah tautan yang diposting oleh @JesperMortensen dan Simon Peck masih relevan?
ItalyPaleAle
5
Amazon mengumumkan dukungan untuk kompresi gzip pada Desember 2015, jadi ini sekarang tidak relevan cukup unggah file dasar dan itu akan berhasil. aws.amazon.com/blogs/aws/…
Sean
15

Jawaban saya adalah lepas landas untuk ini: http://blog.kenweiner.com/2009/08/serving-gzipped-javascript-files-from.html

Membangun jawaban skyler Anda dapat mengunggah versi cz dan js gzip dan non-gzip. Berhati-hatilah dalam memberi nama dan uji di Safari. Karena safari tidak akan menangani .css.gzatau .js.gzfile.

site.jsdan site.js.jgzdan site.cssdan site.gz.css (Anda harus mengatur content-encodingtajuk ke jenis MIME yang benar agar dapat ditayangkan dengan benar)

Kemudian di halaman Anda taruh.

<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 hanya sr_gzipEnabled = true; Ini menguji untuk memastikan browser dapat menangani kode gzip dan menyediakan cadangan jika mereka tidak bisa.

Kemudian lakukan sesuatu yang serupa di footer dengan asumsi semua js Anda ada dalam satu file dan bisa masuk ke dalam footer.

<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> 

UPDATE: Amazon sekarang mendukung kompresi gzip. Pengumuman, jadi ini tidak lagi diperlukan. Pengumuman Amazon

Sean
sumber
terima kasih banyak untuk saran itu. Jika saya memahami Anda dengan benar, Anda sedang menangani kasus di mana browser pengguna tidak dapat membaca file yang di-gzip, yang masih dapat terjadi meskipun menyangkut persentase browser yang cukup kecil saat ini. Salah satu kemungkinan kelemahan dari solusi ini, jika Anda merujuk ke tautan yang saya posting di [ pertanyaan ] pertanyaan saya adalah itu berarti Anda tidak dapat men- cache halaman Anda, karena itu hanya akan berfungsi jika kode Anda dijalankan secara dinamis setiap kali pengguna memuat halaman (yang tentu saja milikku).
Donald Jenkins
@ DonaldJenkins Saya pikir js masih akan di-cache. Ketika Anda membuat tag skrip di js snip, js masih harus dipanggil dan saya percaya bahwa jika ada dalam cache, browser akan menggunakannya dari sana.
Sean
2
Halaman tes blog.kosny.com/testpages/safari-gz menunjukkan bahwa peringatan "Hati-hati penamaan dan uji di Safari. Karena safari tidak akan menangani css.gz atau js.gz" sudah kedaluwarsa. Di Safari 7 di Mavericks, dan di Safari di iOS 7, css.gz dan js.gz berfungsi. Saya tidak tahu kapan perubahan ini terjadi, saya hanya menguji dengan perangkat yang saya miliki.
garyrob
14

Cloudfront mendukung gzipping.

Cloudfront terhubung ke server Anda melalui HTTP 1.0. Secara default, beberapa server web, termasuk nginx, tidak dapat menyajikan konten yang di-gzip ke koneksi HTTP 1.0, tetapi Anda dapat melakukannya dengan menambahkan:

gzip_http_version 1.0

ke konfigurasi nginx Anda. Konfigurasi yang setara dapat ditetapkan untuk server web mana pun yang Anda gunakan.

Ini memang memiliki efek samping membuat koneksi tetap-hidup tidak berfungsi untuk koneksi HTTP 1.0, tetapi karena manfaat kompresi sangat besar, itu pasti layak diimbangi.

Diambil dari http://www.cdnplanet.com/blog/gzip-nginx-cloudfront/

Edit

Melayani konten yang di-gzip dengan cepat melalui Amazon cloud depan adalah berbahaya dan mungkin tidak boleh dilakukan. Pada dasarnya jika server web Anda gzipping konten, itu tidak akan mengatur Panjang Konten dan malah mengirim data sebagai chunked.

Jika koneksi antara Cloudfront dan server Anda terputus dan terputus sebelum waktunya, Cloudfront masih menyimpan hasil parsial dan menyajikannya sebagai versi cache hingga habis masa berlakunya.

Jawaban yang diterima dari gzipping pertama kali pada disk dan kemudian menyajikan versi gzip adalah ide yang lebih baik karena Nginx akan dapat mengatur header Panjang Konten, sehingga Cloudfront akan membuang versi terpotong.

Danack
sumber
5
-1, Jawaban ini tidak ada hubungannya dengan pertanyaan. Nginx! = S3 dan Cloudfront
Jonathan
@Danack, apakah Anda mengalami banyak masalah dengan Cloudfront caching file yang setengah diambil karena masalah ini? Saya mencoba memahami seberapa besar masalah ini bagi Anda dalam praktiknya.
poshest
1
@poshest Itu terjadi. Ada sedikit manfaat untuk melayani gzip dengan cepat (karena gzip begitu cepat di server,) jadi saya mematikannya segera setelah saya melihatnya terjadi. Data terkorupsi adalah masalah yang jauh lebih besar daripada memiliki "waktu untuk byte pertama" menjadi 200 ms lambat dalam kasus yang jarang terjadi di mana konten belum ada dalam format gzip.
Danack
Jika suatu aset kehilangan properti Content-Length di header tetapi termasuk Transfer-Encoding: chunked (seperti yang sering terjadi dengan aset gzip), CloudFront TIDAK akan men-cache aset parsial jika tidak menerima potongan terminasi. Jika kehilangan kedua properti ini, maka mungkin aset yang tidak lengkap di-cache. Lihat: docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/…
Cody Duval
5

Kami telah membuat beberapa optimisasi untuk uSwitch.com baru-baru ini untuk mengompresi beberapa aset statis di situs kami. Meskipun kami menyiapkan seluruh proxy nginx untuk melakukan ini, saya juga telah membuat aplikasi Heroku kecil yang proksi antara CloudFront dan S3 untuk memampatkan konten: http://dfl8.co

Mengingat objek S3 yang dapat diakses publik dapat diakses menggunakan struktur URL sederhana, http://dfl8.co hanya menggunakan struktur yang sama. Yaitu URL berikut ini setara:

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

Kemarin amazon mengumumkan fitur baru, sekarang Anda dapat mengaktifkan gzip pada distribusi Anda.

Ini bekerja dengan s3 tanpa menambahkan file .gz sendiri, saya mencoba fitur baru hari ini dan berfungsi dengan baik. (perlu membatalkan objek Anda saat ini)

Info lebih lanjut

Chris
sumber
0

Anda dapat mengkonfigurasi CloudFront untuk secara otomatis mengkompres file dari jenis tertentu dan melayani file yang dikompresi.

Lihat Panduan Pengembang AWS

Rafi
sumber
Bisakah Anda menambahkan lebih banyak informasi tentang solusi Anda (mungkin contoh) untuk menjadikannya jawaban yang lebih baik.
Yagami Light