AMPとは
AMP(Accelerated Mobile Pages)はモバイルでのウェブページ表示を高速化する手法です。Googleが強く推奨しており、2016年10月よりGoogleのモバイル検索結果の表示にAMPが使用されるようになりました。
高速化のため、AMPページで用いられるHTMLには独自のプロパティや制限があります。cssに関しても、外部ファイルを読み込めない等の制限があります。
RailsでAMP対応する際の問題
AMPでは外部ファイルを読み込めないので、cssをheadタグ内のstyleタグに書かなければなりません。すなわち、ビュー内でcssをrenderする必要があります。しかし、アセットパイプラインにはそんな仕組みはありません。File.read
でcssファイルを読み込んでビューに書き出すといった方法はすぐに考え付きますが、これではコンパイルが必要なSassは使えません。
RailsのビューでSassをrenderする
ではどうやってRailsのビューでSassをrenderするか。答えはSassのgemを直接使うです。なかなか使う機会はないと思いますが、Sassのgemはファイル読込・プリコンパイル・圧縮を一括で行ってくれるスグレモノです。しかも、ワンライナーで書けます!(以下のサンプルでは見やすくするために改行を入れてあります)
以下にサンプルを示します。プリコンパイルと圧縮の処理はヘルパーにまとめ、それをビューで呼び出す形にしています。
def render_css(path)
raw Sass::Engine.for_file("#{Rails.root}/app/assets/stylesheets/#{path}", {
load_paths: ["#{Rails.root}/app/assets/stylesheets"],
style: :compressed
}).to_css
end
style amp-custom=true
= render_css('abc/amp.sass')
通常のstylesheet_link_tag
と同様に使えるようにパス周りを工夫しています。拡張子は必須ですが、Sass::Engine.for_file
が拡張子でフォーマットを判断してくれるので、scssやcssの場合も対応できます。
簡単な解説
Sass::Engine.for_file
Sass::Engine.for_file(filename, options)
は、第一引数にコンパイルしたいファイルのパス、第二引数にコンパイルのオプションをとります。このメソッドはファイルパスに対応したSass::Engine
のインスタンスを生成して返します。このインスタンスはto_css
やrender
といったメソッドを持っており、これらを呼び出すことでコンパイル結果のcssを取得できます。
Sass::Engine.for_fileのオプション
load_pathsでSassの@import
の基準パスを指定できます。上のサンプルでは"#{Rails.root}/app/assets/stylesheets"
を指定して、通常のアセットパイプラインと同様に@import
を使えるようにしています。また、styleにcompressedを指定することで圧縮が有効になります。
render_cssの戻り値
前述のto_css
の結果をそのまま返してしまうと、ビューでcssがhtmlエスケープされてしまいます。
それを防ぐためにraw
メソッドを用い、その戻り値を返すようにしています。
まとめ
たった一行のヘルパーで、AMPページをSassで快適に実装できるようになります。これからAMPに関わる方々のお役に立てれば幸いです。
出典
https://www.ampproject.org/learn/about-amp/
https://japan.googleblog.com/2016/10/amp-1.html
http://sass-lang.com/documentation/Sass/Engine.html