通过S3从Amazon CloudFront提供压缩的CSS和JavaScript


194

我一直在寻找使网站加载速度更快的方法,而我想探索的一种方法是更多地使用Cloudfront。

由于Cloudfront最初不是设计为自定义CDN的,并且因为它不支持gziping,所以到目前为止,我一直在使用它来托管我的所有图像,这些图像在我的站点代码中由它们的Cloudfront cname引用,并经过了优化-futures标头。

另一方面,CSS和javascript文件托管在我自己的服务器上,因为到目前为止,我一直无法从Cloudfront中获得CSS和javascript文件的印象,而获得gzip压缩(大约75%)的收益超过了使用CDN(约占50%):Amazon S3(因此也就是Cloudfront)不支持使用浏览器发送的HTTP Accept-Encoding标头以标准方式提供压缩内容,以表明他们支持gzip压缩,并且因此他们无法即时压缩和提供组件。

因此,直到现在,我的印象是,必须在两种选择之间进行选择:

  1. 将所有资产移至Amazon CloudFront,而不必担心GZipping;

  2. 保持组件自托管,并配置我们的服务器以检测传入的请求,并根据需要即时执行GZipping,这是我到目前为止选择的操作。

还有变通办法来解决这个问题,但本质上这些没有工作。[ 链接 ]。

现在,Amazon Cloudfront似乎支持自定义来源,并且如果您正在使用“自定义来源” [ link ],现在可以使用标准的HTTP Accept-Encoding方法来提供压缩后的内容

到目前为止,我还无法在服务器上实现新功能。我上面链接到的博客文章,这是我发现的唯一详细介绍此更改的文章,似乎暗示着,如果您选择自定义来源,则只能启用gziping(我不想使用的栏变通方法)。我宁愿不要:我发现将Coresponding的文件托管在Cloudfront服务器上并从那里链接到它们更简单。尽管仔细阅读了文档,但我不知道:

  • 新功能是否意味着文件应该通过自定义来源托管在我自己的域服务器,如果是,则通过什么代码设置可以实现此目的;

  • 如何配置css和javascript标头,以确保从Cloudfront压缩后提供它们。

Answers:


202

更新: Amazon现在支持gzip压缩,因此不再需要。 亚马逊公告

原始答案:

答案是gzip CSS和JavaScript文件。是的,你看的没错。

gzip -9 production.min.css

这将产生production.min.css.gz。删除.gz,将其上载到S3(或您使用的任何原始服务器),然后Content-Encoding将文件的头显式设置为gzip

这不是即时的gzip压缩,但是您可以非常轻松地将其打包到构建/部署脚本中。优点是:

  1. 请求文件时,Apache不需要CPU来gzip内容。
  2. 这些文件以最高压缩级别压缩(假定为gzip -9)。
  3. 您正在从CDN提供文件。

假设您的CSS / JavaScript文件(a)缩小了,并且(b)足够大,足以证明在用户计算机上进行解压缩所需的CPU,那么您可以在此处获得显着的性能提升。

只需记住:如果您对CloudFront中缓存的文件进行更改,请确保在进行此类更改后使缓存无效。


37
阅读您的链接后,我必须说博客作者没有消息。“但是,如果用户确实拥有一个不支持gzip编码的浏览器,则该站点的压缩样式表和javascript根本不适合该用户。” 该浏览器可能太旧,无法运行您的样式表和脚本文件。这些用户只占百分之几。
斯勒·约翰逊

3
更新:我解决了。它没有显示的原因是我忘记将Content-Type设置为text / css。如果您这样做,就可以了,尽管出于某种原因,您似乎无法在S3中添加“ Accept-Encoding:Vary”标头(这有助于Google Speed评分),原因如下:[link ]。另外,我设置了Cache-control来缓存资产,但是它似乎并没有在缓存...
Donald Jenkins

32
刚刚通过Google找到了这个消息,很抱歉不得不说这不是一个好建议。尽管不到1%的桌面浏览器无法处理压缩后的内容,但很多移动浏览器却无法处理。有多少取决于您要看的目标受众;但是大多数旧版诺基亚S40都有错误的gzip压缩。正确的方法是“自定义来源”,它指向执行内容压缩并提供正确的HTTP标头的Apache / IIS Web服务器。这是一篇描述其要旨的博客文章:nomitor.com/blog/2010/11/10/…–
Jesper M,

14
2015年初的情况如何?@JesperMortensen和Simon Peck发布的链接仍然有用吗?
ItalyPaleAle 2015年

5
亚马逊于2015年12月宣布支持gzip压缩,因此现在仅上传基本文件就无关紧要了。 aws.amazon.com/blogs/aws/…–
肖恩

15

我的答案是这样的:http : //blog.kenweiner.com/2009/08/serving-gzipped-javascript-files-from.html

根据skyler的答案,您可以上传css和js的gzip和非gzip版本。小心命名并在Safari中进行测试。因为Safari无法处理.css.gz.js.gz归档。

site.jssite.js.jgzsite.csssite.gz.css (你需要设定content-encoding标题,正确的MIME类型,以获得这些服务的权利)

然后在您的页面中放入。

<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只是sr_gzipEnabled = true; 为了测试,以确保浏览器可以处理gzip压缩的代码并提供备份(如果不能)。

然后假设您的所有js都在一个文件中并且可以放在页脚中,然后在页脚中执行类似的操作。

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

更新: Amazon现在支持gzip压缩。公告,因此不再需要。 亚马逊公告


非常感谢您的建议。如果我对您的理解正确,那么您正在解决用户的浏览器无法读取gzip压缩文件的问题,尽管如今它只涉及很小比例的浏览器,但这种情况仍然可能发生。如果您引用我在问题[link ]中发布的链接,此解决方案的一个可能缺点是,这意味着您无法缓存页面,因为只有在每次用户加载时动态运行代码时,页面才会起作用页面(当然是我的页面)。
唐纳德·詹金斯

@DonaldJenkins我认为js仍将被缓存。当您在js片段中构建脚本标签时,仍然必须调用js,我相信,如果它在缓存中,浏览器会从那里使用它。
肖恩

2
测试页blog.kosny.com/testpages/safari-gz指示警告“请小心在Safari中进行命名和测试。因为safari无法处理css.gz或js.gz”,此警告已过时。在Mavericks上的Safari 7和iOS 7上的Safari中,css.gz和js.gz都可以工作。我不知道何时会发生此更改,我只是在测试拥有的设备。
garyrob

14

Cloudfront支持gziping。

Cloudfront通过HTTP 1.0连接到您的服务器。默认情况下,某些网络服务器(包括nginx)不向HTTP 1.0连接提供压缩后的内容,但是您可以通过添加以下内容来告知它:

gzip_http_version 1.0

到您的nginx配置。可以为您使用的任何Web服务器设置等效的配置。

这样做的副作用是使保持活动的连接不适用于HTTP 1.0连接,但是由于压缩的好处是巨大的,因此绝对值得进行权衡。

取自http://www.cdnplanet.com/blog/gzip-nginx-cloudfront/

编辑

通过Amazon云前端动态压缩提供的内容非常危险,因此可能不应该这样做。基本上,如果您的Web服务器正在压缩内容,它将不会设置Content-Length,而是将数据按组发送。

如果Cloudfront与您的服务器之间的连接中断并过早断开,则Cloudfront仍会缓存部分结果,并将其用作缓存的版本,直到过期为止。

先接受gzip压缩然后再提供gzip压缩版本的答案是一个更好的主意,因为Nginx将能够设置Content-Length标头,因此Cloudfront将丢弃截断的版本。


5
-1,这个答案与问题无关。Nginx!= S3和Cloudfront
Jonathan

@Danack,由于这个问题,您在Cloudfront缓存半取回的文件时是否遇到很多问题?我试图了解实际上这对您有多少问题。
豪华的

1
@poshest发生了。即时提供gzip压缩几乎没有什么好处(因为无论如何gzip在服务器上是如此之快),所以我一看到它就关闭了它。在极少数情况下,当内容尚未以gzip压缩的格式存在时,损坏的数据比将“到第一个字节的时间”变慢200ms时要严重得多。
Danack

如果资产在标头中缺少Content-Length属性,但包括Transfer-Encoding:块状(与压缩资产相对应),则CloudFront将不会缓存部分资产(如果未收到终止的块)。如果缺少这两个属性,则可能会缓存不完整的资产。请参阅:docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/…–
科迪·杜瓦尔

5

我们最近对uSwitch.com进行了一些优化,以压缩网站上的某些静态资产。尽管我们设置了一个完整的nginx代理来执行此操作,但是我还组装了一个小的Heroku应用,该应用在CloudFront和S3之间代理以压缩内容:http : //dfl8.co

鉴于可以使用简单的URL结构访问公共可访问的S3对象,因此http://dfl8.co只是使用相同的结构。即以下URL是等效的:

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

5

昨天亚马逊宣布了新功能,您现在可以在您的发行版中启用gzip。

它可以与s3一起使用,而无需自己添加.gz文件,我今天尝试了新功能,效果很好。(但是需要使您当前的对象无效)

更多信息


0

您可以将CloudFront配置为自动压缩某些类型的文件并提供压缩文件。

请参阅AWS 开发人员指南


您能否添加有关解决方案的更多信息(也许是示例),以使其成为更好的答案。
Yagami Light'7
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.