Phục vụ CSS và JavaScript được nén từ Amazon CloudFront qua S3


194

Tôi đã tìm cách để làm cho trang web của mình tải nhanh hơn và một cách mà tôi muốn khám phá là sử dụng Cloudfront nhiều hơn.

Do Cloudfront ban đầu không được thiết kế dưới dạng CDN có nguồn gốc tùy chỉnh và vì nó không hỗ trợ gzipping, nên cho đến nay tôi đã sử dụng nó để lưu trữ tất cả hình ảnh của mình, được tham chiếu bởi tên miền Cloudfront của họ trong mã trang web của tôi và được tối ưu hóa cho đến nay tiêu đề -futures.

Mặt khác, các tệp CSS và javascript được lưu trữ trên máy chủ của riêng tôi, bởi vì cho đến bây giờ tôi có ấn tượng rằng chúng không thể được phục vụ được nén từ Cloudfront và mức tăng từ gzipping (khoảng 75%) vượt xa từ việc sử dụng CDN (khoảng 50 phần trăm): Amazon S3 (và do đó Cloudfront) không hỗ trợ cung cấp nội dung được nén bằng cách sử dụng tiêu đề Mã hóa chấp nhận HTTP được gửi bởi trình duyệt để cho biết hỗ trợ của họ về nén gzip và vì vậy họ không thể Gzip và phục vụ các thành phần một cách nhanh chóng.

Vì vậy, tôi đã rất ấn tượng, cho đến bây giờ, người ta phải lựa chọn giữa hai lựa chọn thay thế:

  1. chuyển tất cả tài sản sang Amazon CloudFront và quên GZipping;

  2. giữ cho các thành phần tự lưu trữ và định cấu hình máy chủ của chúng tôi để phát hiện các yêu cầu đến và thực hiện GZipping nhanh chóng khi thích hợp, đó là điều tôi chọn làm cho đến nay.

Đã cách giải quyết để giải quyết vấn đề này, nhưng về cơ bản chúng không hoạt động . [ liên kết ].

Bây giờ, có vẻ như Amazon Cloudfront hỗ trợ nguồn gốc tùy chỉnh và giờ đây có thể sử dụng phương thức Mã hóa chấp nhận HTTP tiêu chuẩn để phân phát nội dung được nén bằng mã hóa nếu bạn đang sử dụng [ liên kết ] Nguồn gốc tùy chỉnh .

Cho đến nay tôi chưa thể thực hiện tính năng mới trên máy chủ của mình. Bài đăng blog tôi liên kết ở trên, là bài duy nhất tôi tìm thấy chi tiết về sự thay đổi, dường như ngụ ý rằng bạn chỉ có thể kích hoạt gzipping (cách giải quyết của thanh, mà tôi không muốn sử dụng), nếu bạn chọn nguồn gốc tùy chỉnh, mà Tôi thà không: Tôi thấy đơn giản hơn khi lưu trữ các tập tin coresponding trên máy chủ Cloudfront của tôi và liên kết với chúng từ đó. Mặc dù đọc kỹ tài liệu, tôi không biết:

  • liệu tính năng mới có nghĩa là các tệp sẽ được lưu trữ trên máy chủ tên miền của riêng tôi thông qua nguồn gốc tùy chỉnh hay không, và nếu vậy, thiết lập mã nào sẽ đạt được điều này;

  • cách định cấu hình các tiêu đề css và javascript để đảm bảo chúng được phục vụ được nén từ Cloudfront.

Câu trả lời:


202

CẬP NHẬT: Amazon hiện hỗ trợ nén gzip, vì vậy điều này không còn cần thiết nữa. Thông báo của Amazon

Câu trả lời gốc:

Câu trả lời là gzip các tệp CSS và JavaScript. Bạn đã đọc đúng.

gzip -9 production.min.css

Điều này sẽ sản xuất production.min.css.gz. Xóa .gz, tải lên S3 (hoặc bất kỳ máy chủ gốc nào bạn đang sử dụng) và đặt rõ ràng Content-Encodingtiêu đề cho tệp gzip.

Nó không phải là đang di chuyển nhanh, nhưng bạn có thể dễ dàng gói nó vào các tập lệnh xây dựng / triển khai của mình. Những ưu điểm là:

  1. Nó không yêu cầu CPU cho Apache để nén nội dung khi tệp được yêu cầu.
  2. Các tập tin được nén ở mức nén cao nhất (giả sử gzip -9).
  3. Bạn đang phục vụ tệp từ CDN.

Giả sử rằng các tệp CSS / JavaScript của bạn (a) được thu nhỏ và (b) đủ lớn để biện minh cho CPU cần thiết để giải nén trên máy của người dùng, bạn có thể đạt được hiệu suất đáng kể tại đây.

Chỉ cần nhớ: Nếu bạn thực hiện thay đổi đối với tệp được lưu trong bộ nhớ cache trong CloudFront, hãy đảm bảo bạn vô hiệu hóa bộ đệm sau khi thực hiện loại thay đổi này.


37
Sau khi đọc liên kết của bạn, tôi phải nói rằng tác giả blog là không hiểu biết. "Tuy nhiên, nếu người dùng không có trình duyệt không hỗ trợ mã hóa gzip, các bảng định kiểu được nén và javascripts của trang web của bạn sẽ không hoạt động cho người dùng đó." Trình duyệt này có thể đã quá cũ để chạy tệp định kiểu và tệp tập lệnh của bạn. Những người dùng này chiếm một phần trăm.
Skyler Johnson

3
CẬP NHẬT: Tôi đã làm việc ra. Lý do nó không hiển thị là tôi đã quên đặt Kiểu nội dung thành văn bản / css. Nếu bạn làm điều đó, bạn vẫn ổn, mặc dù vì một số lý do, có vẻ như bạn không thể thêm tiêu đề "Chấp nhận mã hóa: Vary" trong S3 (sẽ giúp đánh giá Google Speed) vì những lý do được mô tả ở đây: [link ]. Ngoài ra, tôi đặt Kiểm soát bộ đệm để lưu trữ nội dung, nhưng dường như nó không lưu trong bộ nhớ cache ...
Donald Jenkins

32
Chỉ cần tìm thấy điều này qua Google và tôi rất tiếc phải nói rằng đây không phải là lời khuyên tốt. Trong khi <1% trình duyệt máy tính để bàn không thể xử lý nội dung được nén, khá nhiều trình duyệt di động không thể. Có bao nhiêu tùy thuộc vào đối tượng mục tiêu mà bạn đang xem; nhưng hầu hết các máy Nokia S40 cũ hơn đều có tính năng nén lỗi gzip. Cách thích hợp là "Nguồn gốc tùy chỉnh", trỏ đến máy chủ web Apache / IIS có chức năng nén nội dung và phục vụ các tiêu đề HTTP thích hợp. Đây là một bài viết trên blog mô tả ý chính của nó: nomitor.com/blog/2010/11/10/ trên
Jesper M

14
Tình hình bây giờ thế nào, đầu năm 2015? Các liên kết được đăng bởi @JesperMortensen và Simon Peck có còn phù hợp không?
ÝPaleAle

5
Amazon đã công bố hỗ trợ nén gzip vào tháng 12 năm 2015, vì vậy điều này bây giờ không liên quan chỉ cần tải lên tệp cơ bản và nó sẽ hoạt động. aws.amazon.com/bloss/aws/ trên
Sean

15

Câu trả lời của tôi là cất cánh về điều này: http://blog.kenweiner.com/2009/08/serving-gzipped-javascript-files-from.html

Xây dựng câu trả lời của skyler, bạn có thể tải lên phiên bản gzip và không phải gzip của css và js. Hãy cẩn thận đặt tên và kiểm tra trong Safari. Bởi vì safari sẽ không xử lý .css.gzhoặc .js.gztập tin.

site.jssite.js.jgzsite.csssite.gz.css (bạn sẽ cần phải đặt content-encodingtiêu đề để loại MIME đúng để có được những phục vụ bên phải)

Sau đó trong trang của bạn đặt.

<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 chỉ là sr_gzipEnabled = true; thử nghiệm này để đảm bảo trình duyệt có thể xử lý mã được nén và cung cấp bản sao lưu nếu không thể.

Sau đó, làm một cái gì đó tương tự trong phần chân trang giả sử tất cả các js của bạn nằm trong một tệp và có thể đi vào phần chân trang.

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

CẬP NHẬT: Amazon hiện hỗ trợ nén gzip. Thông báo, vì vậy điều này không còn cần thiết. Thông báo của Amazon


cảm ơn rất nhiều vì lời đề nghị đó Nếu tôi hiểu bạn một cách chính xác, bạn đang giải quyết trường hợp trình duyệt của người dùng không thể đọc được tệp được nén, điều này vẫn có thể xảy ra mặc dù hiện tại nó liên quan đến một tỷ lệ khá nhỏ các trình duyệt. Một nhược điểm có thể có của giải pháp này, nếu bạn tham khảo liên kết tôi đã đăng trong câu hỏi của tôi [link ] là nó có nghĩa là bạn không thể lưu trữ trang của mình, vì nó sẽ chỉ hoạt động nếu mã của bạn được chạy linh hoạt mỗi khi người dùng tải trang (tất nhiên là của tôi).
Donald Jenkins

@DonaldJenkins Tôi nghĩ rằng js vẫn sẽ được lưu trữ. Khi bạn xây dựng thẻ script trong sns js, js vẫn phải được gọi và tôi tin rằng nếu nó nằm trong bộ đệm thì trình duyệt sẽ sử dụng nó từ đó.
Sean

2
Trang thử nghiệm blog.kosny.com/testpages/safari-gz chỉ ra rằng cảnh báo "Hãy cẩn thận đặt tên và kiểm tra trong Safari. Vì safari sẽ không xử lý css.gz hoặc js.gz" đã hết hạn. Trong Safari 7 trên Mavericks và trong Safari trên iOS 7, cả css.gz và js.gz đều hoạt động. Tôi không biết khi thay đổi này xảy ra, tôi chỉ thử nghiệm với các thiết bị tôi có.
garyrob

14

Cloudfront hỗ trợ gzipping.

Cloudfront kết nối với máy chủ của bạn thông qua HTTP 1.0. Theo mặc định, một số máy chủ web, bao gồm nginx, không cung cấp nội dung được nén vào các kết nối HTTP 1.0, nhưng bạn có thể yêu cầu nó thực hiện bằng cách thêm:

gzip_http_version 1.0

để cấu hình nginx của bạn. Cấu hình tương đương có thể được đặt cho bất kỳ máy chủ web nào bạn đang sử dụng.

Điều này có tác dụng phụ là làm cho các kết nối duy trì không hoạt động đối với các kết nối HTTP 1.0, nhưng vì lợi ích của việc nén là rất lớn, nên chắc chắn nó đáng để đánh đổi.

Lấy từ http://www.cdnplanet.com/blog/gzip-nginx-cloudfront/

Biên tập

Việc phục vụ nội dung được nén khi đang di chuyển qua mặt trước đám mây của Amazon rất nguy hiểm và có lẽ không nên thực hiện. Về cơ bản, nếu máy chủ web của bạn gzipping nội dung, nó sẽ không đặt Độ dài nội dung và thay vào đó gửi dữ liệu dưới dạng chunk.

Nếu kết nối giữa Cloudfront và máy chủ của bạn bị gián đoạn và bị cắt sớm, Cloudfront vẫn lưu trữ kết quả một phần và phục vụ như phiên bản được lưu trong bộ nhớ cache cho đến khi hết hạn.

Câu trả lời được chấp nhận của việc gzipping nó trước trên đĩa và sau đó phục vụ phiên bản được nén là một ý tưởng tốt hơn vì Nginx sẽ có thể đặt tiêu đề Độ dài nội dung và do đó, Cloudfront sẽ loại bỏ các phiên bản rút gọn.


5
-1, Câu trả lời này không liên quan gì đến câu hỏi. Nginx! = S3 và Cloudfront
Jonathan

@Danack, bạn có gặp phải nhiều vấn đề với các tệp được khôi phục một nửa bộ nhớ đệm của Cloudfront vì vấn đề này không? Tôi đang cố gắng hiểu vấn đề này là gì đối với bạn trong thực tế.
chắc chắn nhất vào

1
@plhest Nó đã xảy ra. Có rất ít lợi ích khi phục vụ gzipped khi đang di chuyển (vì gzip rất nhanh trên máy chủ,) vì vậy tôi đã tắt nó ngay khi tôi thấy nó xảy ra. Dữ liệu bị hỏng là một vấn đề lớn hơn nhiều so với việc "thời gian đến byte đầu tiên" bị chậm 200ms trong những trường hợp hiếm hoi khi nội dung không tồn tại ở định dạng được nén.
Danack

Nếu một tài sản bị thiếu thuộc tính Độ dài nội dung trong tiêu đề nhưng bao gồm Mã hóa chuyển: chunked (như trường hợp với tài sản được nén), CloudFront sẽ KHÔNG lưu trữ một phần tài sản nếu nó không nhận được một đoạn kết thúc. Nếu nó thiếu cả hai thuộc tính này thì có thể lưu trữ một tài sản chưa hoàn chỉnh. Xem: docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/ mẹo
Cody Duval

5

Gần đây, chúng tôi đã thực hiện một số tối ưu hóa cho uSwitch.com để nén một số tài sản tĩnh trên trang web của chúng tôi. Mặc dù chúng tôi thiết lập toàn bộ proxy nginx để thực hiện việc này, tôi cũng đã kết hợp một ứng dụng Heroku nhỏ hỗ trợ giữa CloudFront và S3 để nén nội dung: http://dfl8.co

Có thể truy cập các đối tượng S3 có thể truy cập công khai bằng cấu trúc URL đơn giản, http://dfl8.co chỉ sử dụng cùng cấu trúc. Tức là các URL sau là tương đương:

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

5

Hôm qua amazon đã công bố tính năng mới, giờ đây bạn có thể kích hoạt gzip trên bản phân phối của mình.

Nó hoạt động với s3 mà không cần thêm tệp .gz, tôi đã thử tính năng mới ngày hôm nay và nó hoạt động rất tốt. (cần phải vô hiệu hóa các đối tượng hiện tại của bạn)

Thêm thông tin


Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.