Amazon CloudFrontからS3経由でgzip圧縮されたCSSおよびJavaScriptを提供する


194

私は自分のサイトの読み込みを速くする方法を探していましたが、探求したい1つの方法はCloudfrontをより活用することです。

CloudfrontはもともとカスタムオリジンCDNとして設計されておらず、gzip圧縮をサポートしていなかったため、これまでのところ、私のサイトコードでCloudfront cnameによって参照され、farで最適化されたすべての画像をホストしています。 -futuresヘッダー。

一方、CSSとjavascriptファイルは自分のサーバーでホストされています。これまで、Cloudfrontからgzipで提供することはできず、gzipによる利益(約75%)がそれよりも大きいという印象がありました。 CDN(約50%)の使用から:Amazon S3(およびCloudfront)は、gzip圧縮のサポートを示すためにブラウザーから送信されるHTTP Accept-Encodingヘッダーを使用して、標準的な方法でgzip圧縮されたコンテンツの提供をサポートしませんでした。そのため、Gzipを実行してコンポーネントをその場で提供することができませんでした。

したがって、私は今まで、2つの選択肢から選択する必要があるという印象を受けていました。

  1. すべてのアセットをAmazon CloudFrontに移動し、GZippingを忘れます。

  2. コンポーネントを自己ホストし、受信リクエストを検出し、必要に応じてオンザフライのGZippingを実行するようにサーバーを構成します。これは、これまでのところ私が選択した方法です。

この問題を解決するための回避策はありました、基本的にこれらは機能しませんでした。[ リンク ]。

現在、Amazon Cloudfrontはカスタムオリジンをサポートしているようですカスタムオリジン [ リンク ] を使用している場合、gzip圧縮されたコンテンツを提供するために標準のHTTP Accept-Encodingメソッドを使用できるようになりました

今のところ、サーバーに新機能を実装することはできません。上記にリンクしたブログ投稿は、変更の詳細を確認した唯一の記事ですが、カスタムオリジンを選択した場合、gzip圧縮(バーの回避策、私は使用しない)のみを有効にできることを意味しているようです。どちらかといえば、Cloudfrontサーバーで対応するフィールドをホストし、そこからリンクする方が簡単だと思います。ドキュメントを注意深く読んだにもかかわらず、私は知りません:

  • 新しい機能が、ファイルがカスタムオリジンを介して自分のドメインサーバーでホストされる必要があることを意味するかどうか。

  • cssおよびjavascriptヘッダーを構成して、Cloudfrontからgzipで提供されるようにする方法。

回答:


202

更新: Amazonはgzip圧縮をサポートするようになったため、これは不要になりました。 アマゾン発表

元の答え:

答えは、CSSファイルとJavaScriptファイルをgzipすることです。はい、あなたはその権利を読みます。

gzip -9 production.min.css

これが生成されproduction.min.css.gzます。を削除し.gz、S3(または使用しているオリジンサーバー)にアップロードしContent-Encodingて、ファイルのヘッダーをに明示的に設定しますgzip

オンザフライのgzip圧縮ではありませんが、ビルド/デプロイメントスクリプトに非常に簡単にまとめることができます。利点は次のとおりです。

  1. ファイルが要求されたときに、ApacheがコンテンツをgzipするためのCPUは必要ありません。
  2. ファイルは最高の圧縮レベルでgzip圧縮されます(ただし、 gzip -9)。
  3. CDNからファイルを提供しています。

CSS / JavaScriptファイルが(a)縮小され、(b)ユーザーのマシンで解凍するために必要なCPUを正当化するのに十分な大きさであると仮定すると、ここでパフォーマンスを大幅に向上させることができます。

覚えておいてください。CloudFrontにキャッシュされているファイルを変更する場合は、このタイプの変更を行った後、キャッシュを無効にしてください。


37
あなたのリンクを読んだ後、私はブログの作者が知らされていないと言う必要があります。「ただし、ユーザーがgzipエンコードをサポートしていないブラウザを使用している場合、サイトの圧縮スタイルシートとJavaScriptは、そのユーザーには機能しません。」このブラウザーはおそらく古すぎてスタイルシートとスクリプトファイルを実行できません。これらのユーザーは、1分の1を占めています。
スカイラージョンソン、

3
更新:うまくいきました。表示されなかった理由は、Content-Typeをtext / cssに設定するのを忘れていたためです。理由のために(Googleのスピードの評価で役立つだろう)S3におけるヘッダは、ここで説明:何らかの理由で、それはそうですが、あなたは、その、あなたしている罰金を行う場合は、「ヴァリ・エンコーディングを受け入れる」:追加することはできません[リンク ]。また、私はアセットをキャッシュするようにキャッシュコントロールを設定しましたが、それはそれをキャッシュしていないようです...
ドナルドジェンキンス

32
グーグル経由でこれを見つけたところ、申し訳ありませんが、これはそれほど良いアドバイスではありません。デスクトップブラウザーの1%未満はgzip圧縮されたコンテンツを処理できませんが、多くのモバイルブラウザーは処理できません。どれだけ多くがあなたが見ているどのターゲットオーディエンスに依存します。しかし、ほとんどの古いNokia S40には、バグのあるgzip圧縮などがあります。適切な方法は、コンテンツの圧縮を行い、適切なHTTPヘッダーを提供するApache / IIS Webサーバーを指す「カスタムオリジン」です。ここでの要点を記述する1つのブログ記事は次のとおりです。nomitor.com/blog/2010/11/10/...
ジェスパーM

14
2015年初頭の状況はどうですか?@JesperMortensenおよびSimon Peckによって投稿されたリンクはまだ関連していますか?
ItalyPaleAle 2015年

5
Amazonは2015年12月にgzip圧縮のサポートを発表したので、これは無関係です。基本的なファイルをアップロードするだけで動作します。 aws.amazon.com/blogs/aws/...
ショーン

15

私の答えはこれの離陸です: http //blog.kenweiner.com/2009/08/serving-gzipped-javascript-files-from.html

スカイラーの回答を基に、CSSとJSのgzipバージョンと非gzipバージョンをアップロードできます。Safariでの命名とテストには注意してください。サファリはファイル.css.gz.js.gzファイルを処理しないからです。

site.jsand site.js.jgzand site.cssand site.gz.csscontent-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が1つのファイルにあり、フッターに移動できると想定して、フッターで同様のことを行います。

<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圧縮されたファイルを読み取ることができないという問題に対処しています。このソリューションの考えられる欠点の1つは、私の質問[リンク ] に投稿したリンクを参照する場合、ユーザーがロードするたびにコードが動的に実行される場合にのみ機能するため、ページをキャッシュできないことですページ(もちろん私のものです)。
ドナルドジェンキンス

@DonaldJenkins jsはまだキャッシュされると思います。js snipでスクリプトタグを作成するときも、jsを呼び出す必要があります。キャッシュにある場合、ブラウザーはそこからそれを使用すると思います。
ショーン、

2
テストページblog.kosny.com/testpages/safari-gzは、「Safariはcss.gzまたはjs.gzを処理しないため、Safariでの命名とテストには注意してください」という警告が古くなっていることを示しています。MavericksのSafari 7とiOS 7のSafariでは、css.gzとjs.gzの両方が機能します。この変更がいつ発生したかはわかりませんが、私が持っているデバイスでのみテストしています。
garyrob 2013年

14

Cloudfrontはgzip圧縮をサポートしています。

CloudfrontはHTTP 1.0経由でサーバーに接続します。デフォルトでは、nginxを含む一部のWebサーバーはgzip圧縮されたコンテンツをHTTP 1.0接続に提供しませんが、次のように追加することで実行するように指示できます。

gzip_http_version 1.0

あなたのnginx設定に。同等の設定は、使用しているどのWebサーバーにも設定できます。

これには、HTTP 1.0接続ではキープアライブ接続が機能しないという副作用がありますが、圧縮のメリットは非常に大きいため、トレードオフの価値があります。

http://www.cdnplanet.com/blog/gzip-nginx-cloudfront/から取得

編集する

Amazonクラウドフロントを介してオンザフライでgzip圧縮されたコンテンツを提供することは危険であり、おそらく実行すべきではありません。基本的に、Webサーバーがコンテンツをgzip圧縮している場合は、Content-Lengthを設定せず、データをチャンクとして送信します。

Cloudfrontとサーバー間の接続が中断され、途中で切断された場合でも、Cloudfrontは部分的な結果をキャッシュし、期限が切れるまでキャッシュバージョンとして機能します。

NginxはContent-Lengthヘッダーを設定できるため、Cloudfrontが切り捨てられたバージョンを破棄するため、最初にディスクにgzip圧縮してからgzip圧縮されたバージョンを提供するという承認された回答の方が適しています。


5
-1、この回答は質問とは関係ありません。Nginx!= S3およびCloudfront
ジョナサン

@Danack、この問題が原因で、Cloudfrontが半分取得したファイルをキャッシュする際に多くの問題が発生しましたか?これが実際にどの程度の問題であったかを理解しようとしています。
2016年

1
@poshest起こりました。(とにかくサーバー上でgzipが非常に高速であるため)オンザフライでgzipを提供するメリットはほとんどなかったため、それが発生するのを確認したらすぐにオフにしました。破損したデータは、コンテンツがまだgzip圧縮された形式で存在しないまれなケースで、「最初のバイトまでの時間」を200ms遅くするよりもはるかに大きな問題です。
Danack 2016年

アセットのヘッダーにContent-LengthプロパティがなくてもTransfer-Encoding:チャンクが含まれている場合(gzipされたアセットの場合によくあることです)、CloudFrontは、終了チャンクを受信しない場合、部分的なアセットをキャッシュしません。これらの両方のプロパティがない場合、不完全なアセットがキャッシュされる可能性があります。参照:docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/...
コーディデュバル

5

最近、uSwitch.comに対していくつかの最適化を行って、サイト上の静的アセットの一部を圧縮しました。これを行うためにnginxプロキシ全体をセットアップしましたが、CloudFrontとS3の間でプロキシしてコンテンツを圧縮する小さなHerokuアプリも作成しました:http : //dfl8.co

公的にアクセス可能なS3オブジェクトが単純なURL構造を使用してアクセスできる場合、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

昨日、amazonが新機能を発表しました。ディストリビューションでgzipを有効にできます。

自分で.gzファイルを追加しなくてもs3で動作します。今日、私は新機能を試しましたが、うまく動作します。(ただし、現在のオブジェクトを無効にする必要があります)

より詳しい情報


0

特定のタイプのファイルを自動的に圧縮し、圧縮されたファイルを提供するようにCloudFrontを構成できます。

AWS 開発者ガイドを参照


より良い答えにするために、ソリューションに関する情報(例)を追加できますか?
八神ライト
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.