アセットパイプラインとは
目的
- アセットパイプラインの4つの主な機能を理解します。
- アセットパスの特定
- アセットマニフェストがCSSとJSの連結を提供する方法を知っています。
- SASSやCoffeeScriptのような前処理言語を使用する
- 資産フィンガープリントの定義
概要
長い間、JavaScriptとCSSをwebアプリケーション開発の後付けとして扱いました。 画像、スタイルシート、Javascriptなどのすべてのアセットコードは、public
という巨大なフォルダに保持され、Railsアプリケーションのコンテキストの外で提供されました。 ウェブが進化するにつれて、それはもはや意味がありませんでした。
アセットパイプラインは、スタイルシート、Javascript、および画像を管理するためのRailsの答えです。
アセットパス
多くのファイルがwebアプリケーションの作成に入ります。 CSSファイルとJavaScriptファイルだけでは整理が難しい場合があります。 私たちはどのようなフォルダを作成しますか? どのファイルがどこに行くのですか? アセットパイプラインは、この問題に対する答えを提供します。 私たちはアプリケーションで物事を非常に整理しなければなりませんが、コードの概念や単位ごとに別々のファイルとフォルダを保持することで、2つの問題があります。
- Railsはどのように物事がどこにあるかを知っていますか? カレンダー JSファイルは
app/assets/javascripts/calendar.js
またはvendor/javascripts/calendar.js
ですか? - ページの読み込みが非常に遅くなるため、各ファイルを別々に提供したくありません。 読みやすさと編成のために別々の小さなファイルを維持するのは理にかなっていますが、ブラウザの場合は、これらの小さなファイルをすべてまとめて1つのJSファイルと1つのCSSファイルをロードしたいと思います。 このプロセスは連結と呼ばれます。
私たちの最初の問題について話しましょう:Railsはどこを見るべきかをどのように知っていますか? アセットパイプラインには、これを処理するためのアセットパスと呼ばれる概念があります。 フォルダパスの組み合わせであるPATH環境変数があるBASHのように、アセットパスはRailsがアセットを探すためのフォルダパスの組み合わせです。 アセットパスがどのように構成されているかの例を見てみましょう。
Rails.application.config.assets.paths =>
これらのフォルダのいずれかにアセットを配置すると、アプリケーションのURL’/assets’を介してアクセスできます。 Railsが検索する追加のフォルダがある場合は、そのフォルダをアセットパスに追加することができます。 これはファイルconfig/initializers/assets.rb
で行われます。
Rails.application.config.assets.paths << "New Path"
アセットを任意の場所に配置し、アセットパスを設定し、単一の’/assets’URLを介してアクセスできます。
マニフェストと連結
どこにでもファイルを置くことができるようになったので、それらをwebページに含めるにはどうすればよいですか? アセットパイプラインはマニフェストファイルを使用して、何をロードすべきかをRailsに指示します。 このマニフェストファイルは、アプリケーションが必要とするすべてのCSSとJSファイルを一覧表示できる中央の場所です。 これはJSやCSSの機能ではなく、アセットパイプラインです。 JSマニフェストファイルの例は次のとおりです。
File:app/assets/javascripts/application。js
//= require jquery//= require calendar
マニフェストファイルをjavascript_include_tag
でレイアウトに含めると、アセットパイプラインはアセットパスにリストされているすべてのファイルを検索します。 私たちはカレンダーを必要とする方法に注意してください。 このファイルはapp/assets/javascripts/calendar.js
にありますが、完全なパスではなく名前のみを指定しました。 アセットパイプラインは、指定した名前のファイルの構成されたすべてのパスを検索します。
発見可能性の問題を解決したので、連結について話しましょう。 先に説明したように、ブラウザにファイルを1つずつロードしたくありません。 ブラウザからの小さなダウンロードよりも、1つのダウンロードを実行する方が良いでしょう。 Railsで設定したマニフェストファイルは、それらにリストされているファイルを本番環境の1つのファイルに自動的に連結します。 これは、デバッグを困難にする可能性があるため、アプリケーションを開発しているときには最良の選択肢ではないかもしれません。 しかし、開発モードで実行しているとき、Railsは実際には各ファイルを別々に提供します。 何もする必要はありません。
最後に、私たちの資産マニフェストに電力を供給するスプロケット指令については、後で詳しく説明します。
前処理
アプリケーション内の定義済みの場所のセットからファイルを結合してロードできることは、アセットパイプラインの大きな利点です。 それは始まりに過ぎません。 Railsを介してアセットをロードしているので、より良いCSSを書くためのSCSSや、よりクリーンなJSのためのCoffeescriptのような一般的な言語を使用してファイルを前処理することができます。 テーマという名前のアセットを作成する場合。css。scssでは、テーマを提供する前にSCSSプリプロセッサを介してファイルを実行するように資産パイプラインに指示しています。ブラウザへのcss。 SCSSプリプロセッサは、ファイルをCSSにコンパイルします。 私たちがしなければならなかった唯一のことは、ファイルに正しいファイル拡張子.scss
を提供することでした。
Fingerprinting
最後に説明する利点はFingerprintingですが、まずそれが解決するのに役立つ問題について話しましょう。 私たちは、ブラウザにファイルを提供するとき、彼らは将来的に再びそれらをダウンロードしないようにキャッシュされる可能性があります。 あなたが尋ねるかもしれないキャッシングとは何ですか?
何かをキャッシュすることは、時間のかかる操作のコピーをローカルに保持することを意味し、入力と出力がまったく同じになる場合に高価な操作を キャッシュは通常、キー値ストアであり、値は高価な操作に対する答えであり、キーはそのアイテムに固有のものです。 サーバーからページを要求し、サーバーから同じページを再度要求する場合、その要求を満たす最も簡単な方法は、最後に取得したもののコピーを実際にローカルに保 ブラウザは、応答とともに送信されるヘッダーを使用して、行った要求に対して取得した応答の多くをキャッシュします。 ヘッダーは、ページの有効期限が切れる前にページが”新鮮”に残っている時間をブラウザに伝えます。’ページの有効期限が切れると、ブラウザはページのキャッシュを更新するための新しい要求を行います。 私たちは、最速の要求は行われていない要求であると言います。 また、多くの場合、キャッシュの無効化は、コンピュータサイエンスの二つの難しい問題の一つであると言われているので、あなたが物事をキャッシ キャッシュは、私たちのために帯域幅を節約し、ユーザーのための速度のブーストを提供します。 これは、ファイルを変更し、ブラウザのキャッシュに保存されている古いバージョンではなく、すべてのユーザーに新しいバージョンを取得させるまで素晴ら しかし、ファイルを変更したことをブラウザにどのように知らせるのですか? 新しいバージョンが古いバージョンと同じ名前を持つ場合、ブラウザはキャッシュから古いファイルを引き続き使用します。 ブラウザが古いファイルを提供し続けないように、内容が変更されたときにファイル名を変更する方法が必要です。
From The Rails Guides Primer
“フィンガープリントは、ファイル名の名前をファイルの内容に依存させる技術です。 ファイルの内容が変更されると、ファイル名も変更されます。 静的または頻繁に変更されないコンテンツの場合、これにより、サーバーや展開日が異なる場合でも、ファイルの2つのバージョンが同一であるかどうかを簡単に判断することができます。
ファイル名が一意で、その内容に基づいている場合、HTTPヘッダーを設定して、どこのキャッシュ(Cdn、Isp、ネットワーク機器、webブラウザなど)でも、コンテンツの自 コンテンツが更新されると、指紋が変更されます。 これにより、リモートクライアントはコンテンツの新しいコピーを要求します。 これはキャッシュバスティングと呼ばれます。
スプロケットがフィンガープリントに使用する手法は、ファイル名の最後にコンテンツのハッシュを追加することです。 たとえば、global.css
という名前のCSSファイルを取ります。 スプロケットは、次のようにファイル名の最後にハッシュ908e25f4bf641868d8683022a5b62f54
を追加します:
global-908e25f4bf641868d8683022a5b62f54.css
古いバージョンのRailsを使用している場合(Rails2.x)では、組み込みのヘルパーでリンクされているすべてのアセットに日付ベースのクエリ文字列を追加する戦略が使用されていました。 これはそうのように見えました:
global.css?1309495796
クエリ文字列の戦略には、いくつかの欠点があります:
- すべてのキャッシュが、ファイル名がクエリパラメータによってのみ異なるコンテンツを確実にキャッシュするわけではありません。
- Steve Soudersは、”キャッシュ可能なリソースのクエリ文字列を避けることをお勧めします。”あなたの要求の5-20%がキャッシュされません。 特にクエリ文字列は、キャッシュの無効化のために一部のCdnではまったく機能しません。
- ファイル名は、マルチサーバー環境のノード間で変更できます。
- Rails2のデフォルトのクエリ文字列。xは、ファイルの変更時刻に基づいています。 アセットをクラスターにデプロイする場合、タイムスタンプが同じであるという保証はなく、要求を処理するサーバーによって異なる値が使用されます。
- キャッシュの無効化が多すぎます。
- 静的アセットがコードの新しいリリースごとにデプロイされると、これらのすべてのファイルのmtime(最終変更時刻)が変更され、すべてのリモートクライア
フィンガープリントは、ファイル名がその内容に基づいて一貫していることを保証することによって、これらの問題をすべて修正します。
Fingerprintingは、本番環境ではデフォルトで有効になっており、他のすべての環境では無効になっています。 設定でconfig.assets.digest
オプションを使用して有効または無効にすることができます。”
結論
アセットパイプラインは確かに複雑で、パブリックフォルダからアセットを提供するだけで、デバッグするのは難しい場合があります。 それを使用する方法を学ぶことは、私たちの時間と頭痛を節約することによって、長期的には報われるでしょう。 それが私たちのために解決するすべての問題について考えてみてください。
- アセットパス
- マニフェストと連結
- 前処理
- フィンガープリント
最後に、DHHがアセットパイプラインを紹介する基調講演をチェックしてくださ