backstage

合唱音源の新着情報の舞台裏

【Rails】AMP(Accelerated Mobile Pages)に合唱音源の新着情報.comを無理矢理対応させる

昨年、Google等によってAMP (Accelerated Mobile Pages)というプロジェクトが公開されました。

www.suzukikenichi.com

GoogleにWebページの情報をキャッシュさせて検索結果と一緒に返すことで、検索結果表示を高速化するというモノです。 特に合唱音源の新着情報.comのような弱小サーバ上に適当設定で動いており3ヶ月に1度くらい定期的にサービスダウンするようなWebサイトの管理者にとっては、Googleの強固なサーバ上で高速にキャッシュを返してくれる仕組みが提供されるのは朗報です。

以下に日本語の公式情報もあります。

googledevjp.blogspot.jp

詳細は上記のブログ等の方が詳しいので説明は置いておいて、さっそく対応してみたいと思いました。

前提条件

$ rails --version
Rails 4.2.1

http://合唱音源の新着情報.com/request/sound/615 というURLに対して
http://合唱音源の新着情報.com/request/sound/615.amp というURLでAMP版のテンプレートを表示させようと思います。

ampテンプレート追加対応

まず、Railsで .ampというテンプレートファイルを読み込むようにします。

コントローラに下記追加

    respond_to do |format|
      format.html
      format.amp{
        request.format = :amp
      }
    end

config/initializers/mime_types.rbに下記追加

Mime::Type.register "text/html", :amp

これで、sound.html.erbという普段使っているテンプレートファイルに対して、新たにsound.amp.erbというファイルでamp版テンプレートを表示できるようになりました。

AMPの仕様に沿ってコーディング

AMPはだいたい通常のHTMLに準拠していますが、ところどころ仕様が異なります。

まずはGitHubからサンプルテンプレートを持ってきて、なにも考えずにsound.amp.erbに貼り付けてみました。

https://github.com/ampproject/amphtml/tree/master/examples

GoogleChromeに搭載されているチェックツールを使って、文法をチェックできる ようなので、このツールが吐き出すログを見ながらコーディングしていきます。

URLの末尾に「#development=1」と付けて開発者ツールを起動すると、デバッグ情報が表示されます。

f:id:s2terminal:20160321233645p:plain

コンソール上に「AMP validation successful.」と出れば成功です。

さてここから本来のページにあるコンテンツを持って来ます。 適当にコピペしてChromeのチェックツールを調べると色々とエラー箇所を教えてくれますので、それに沿ってコーディングしていきます。

合唱音源の新着情報は大した情報のないペラペラなWebページですので、簡単に移植できるはずです。

twitterを埋め込む

AMPではJavaScriptを使えないようですが、サンプルテンプレートのtwitter.amp.htmlにある通り、AMPは <amp-twitter> という独自タグによるtwitter埋め込みをサポートしています。 合唱音源の新着情報はtwitterに過度に依存したWebサービスであるため、これを使わない手は無さそうです。

<amp-twitter width=390 height=330 layout="responsive" data-tweetid=<%= @tweet.tweet_id %>></amp-twitter>

これだけの記述でtwitterを埋め込むことができます。

CSSを埋め込む

AMPは外部CSSを使うことができず、テンプレート内 <style> タグに記述しなければなりません。 ガラケーを思い出すような仕様です。

AssetPipelineを使っているので、コンパイル済みのアセットファイルの中身だけをうまくテンプレート内に吐き出したかったのですが、どうにもスマートな方法がありそうで見当たりません。 なので AssetPipelineを通して配信されたCSSファイルのURLをhttpクライアントでぶっ叩いてダウンロードする という力技を使います。

Rails標準のstylesheet_link_tagヘルパー の実装を参考に、下記のようなヘルパーを作って読み込ませてみます。 (ホスト名ベタ打ちな所とか良い子は真似しないように)

  def css_tag_amp(*sources)
    options = sources.extract_options!.stringify_keys
    path_options = options.extract!('protocol').symbolize_keys

    sources.uniq.map { |source|
      require 'open-uri'
      host = '合唱音源の新着情報.com'
      path = path_to_stylesheet(source, {host: host}.merge!(path_options))
      content_tag(:style, URI(path).read.encode("UTF-8"), options)
    }.join("\n").html_safe
  end

これでCSSファイルの内容をテンプレート内に表示できました。

が、下記のエラーが出てしまいます。

f:id:s2terminal:20160321234456p:plain

The author stylesheet specified in tag 'style amp-custom' is too long - we saw 254121 bytes whereas the limit is 50000 bytes. (see https://www.ampproject.org/docs/reference/spec.html#maximum-size)

とのことで、CSSファイルは50KBまでだそうですが、254KBもあるそうです。 そりゃ、bootstrapの本体まるごと突っ込んでまとめてコンパイルなどしていればそうなると思います。

面倒だったのでとりあえず CSSは無し で行きます。 AMP用の軽量CSSの手配は今後の課題ということで...

そんなこんなで色々やって、エラーをひとつずつ処理していきます。 細かいところだと、bullet の画面下部に出るエラーメッセージもAMPにおいてはエラーとなってしまうため、AMPのデバッグ時には消したりしました。

  Bullet.add_footer   = false

必要なコンテンツを盛り込んだ上でコンソール上に「AMP validation successful.」と出れば成功です。

f:id:s2terminal:20160321234710p:plain

CSSが無いせいで ◯知県合唱連盟の公式サイトのような 20世紀のホームページのような見た目になってしまいましたが、これが2016年の最新のトレンドであるAMP用Webページです。

忘れずに、元のページからAMPページヘlink rel=amphtml を貼るようにして完成です。

まとめ

いくつか課題はありますが、無事にAMP対応のページを公開できました。 例:今年を歌おうプロジェクト 松下耕『今年』の合唱動画 - 合唱音源の新着情報.com

実際にGoogle検索結果へAMPはまだ対応されていませんので、このページを検索結果上で確認することはできません。正しく対応できているのかどうかは不明です。(上手く行っていれば、数日の間にGoogle Search Console上に何らかの反応があると思います)

課題としてはCSSファイルをなんとかスマートな方法で用意したいのですが、AMPと通常Webページのダブルメンテになるとつらいです。 RSS配信のように極力AMP側の装飾を薄くするか、AMP版と通常WebページとでうまくCSSを共有する仕組みを作っておきたいと思いました。

本格的に導入するならばAMPのバリデーションは自動テストもしたい所です。 GoogleによるとChromeの開発者ツールだけでなくバリデーション用のAPIが公開される予定のようですので、そちらに期待です。

追記

追加で 構造化データマークアップが必要だった ので、対応しました。

s2terminal.hatenablog.com

参考文献