Googleさんが発表したモバイル端末での表示高速化のAMP HTMLに対応してみたよ、という話です。

Introducing the Accelerated Mobile Pages Project, for a faster, open mobile web

概要などは上記見てもらえれば感じはつかめると思いますし、日本語で紹介してる記事だと Kenichi Suzukiさんの紹介記事を見ると分かるかと思います。

なぜやってみようかと思ったかというと、「javascriptが無い静的なHTMLとCSSのページは爆速で表示したるで!」というGoogleさんの粋な計らいかと勘違いし、ほとんどが静的なページであるこのブログもサクーっと対応できたりするんじゃね、と思ったからですが、ちょっと苦労しました。

なおブログを完全に対応させたのではなく、記事ページのみ別にAMP HTML用の記事を出力しています。

通常記事
http://masup.net/2015/10/successfully-using-design-a-border.shtml
AMP HTML
http://masup.net/amp/2015/10/successfully-using-design-a-border.shtml

BBCなどの対応しているメディアも大体がそれぞれに出力しているみたいですね。やはり完全に移行するのはかなりEdgeなことなのでしょう。

その場合は、通常記事には<link rel="amphtml" href="hoge.apm.html" />を、APM HTMLには<link rel="canonical" href="hoge.html" />を設定して、AMP HTMLの記事があることを知らせているようです。

仕様

仕様は、Githubリポジトリにまとめられておりますがざっくり言うと

  • フォーマットにきっちりしたがってや
  • JSON-LD以外の javascript 禁止な
  • link要素はrel:canonicalだけ。CSS読み込みも原則禁止
  • img, video, audio, iframeは、使わんと代わりにカスタムエレメンツつこてや
  • object, form, inputとかも禁止

うう、高速化の道は険しい...

フォーマット

これは公式からまんま持ってきますが、htmlamp or を付与し、ライブラリ関係を読み込んでいます。え、絵文字文化。。。

CSSを別途定義する場合は、style要素を使ってインラインで埋め込みます。

<!doctype html>
<html ⚡>
  <head>
    <meta charset="utf-8">
    <link rel="canonical" href="hello-world.html" >
    <meta name="viewport" content="width=device-width,minimum-scale=1,initial-scale=1">
    <style>body {opacity: 0}</style><noscript><style>body {opacity: 1}</style></noscript>
    <script async src="https://cdn.ampproject.org/v0.js"></script>
  </head>
  <body>Hello World!</body>
</html>
via a ampproject/amphtml on Github

ただし、後述するValidatorで検証すると、上記をコピペしてもviewportの箇所でエラーが出るので、このブログのAMP HTMLでは、仕方なくuser-scalable=noありの記述をしています。

<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no,minimal-ui" />

AMP HTML Components

いろいろと制限がある中でもリッチな表現をしたり、広告を表示したりするには、AMP HTMLフレームワークが用意しているカスタムエレメンツを使います。先ほども触れましたが、imgの代わりにはamp-imgというカスタムエレメンツが用意されており、他にもAdwordsなどの広告表示、アクセス解析、ツイートの埋め込み、カルーセルなどのコンポーネントが用意されています。

Githubリポジトリをざっと見た感じだと、「ユーザーによる拡張も考えてなくは無いけど、今はコアコンポーネントに集中するで」的なことなので、まずは与えられてるもののみで作ることになります。

amp-img

img要素の代わりに画像を表示するカスタムエレメンツです。属性としては、

  • src
  • srcset
  • alt
  • width
  • height

などimgと共通のものや、新たに

layout
値にresponsiveを取ると可変幅を許容する
attribution
著作権表示などを記載する

といったものが加えられています。

またwidthheightは必須となっていますが、layout="responsive"を付与することで、アスペクト比を維持した可変のボックス内にimgが配置され、レスポンシブな表示をさせることができます。

高速化って意味では一応、lazyloadとかしてくれる感じです。

記述サンプル
<amp-img layout="responsive"
            width="1280" height="640"
            alt="border-bottom: 5px linear-gradient(...)とか出来たら便利かも"
            src="http://masup.net/images/border_gradient.png" >
</amp-img>
ライブラリ適用後とカスタムエレメンツの中身
<amp-img layout="responsive"
            width="1280" height="640"
            class="-amp-element -amp-layout-responsive -amp-layout-size-defined -amp-layout"
            alt="border-bottom: 5px linear-gradient(...)とか出来たら便利かも"
            src="http://masup.net/images/border_gradient.png"
            id="AMP_1" >
<i-amp-sizer style="display: block; padding-top: 50%;"></i-amp-sizer>
<img amp-img-id="AMP_1" alt="border-bottom: 5px linear-gradient(...)とか出来たら便利かも" class="-amp-fill-content -amp-replaced-content" width="1280" height="640" src="http://masup.net/images/border_gradient.png">
</amp-img>

このブログはMovable Typeで運用しており、前述のとおりAMP HTML用に別途HTMLを出力しています。よって本文中のimg要素をそのまま書き換えてしてしまうわけにはいかず、AMP HTML用に出力する時のみ、記事本文中のimgamp-imgに置換して、layout属性を付与して出力しています。

amp-ad

このブログでは記事下部にAdwordsの広告を貼っていますが、そちらはamp-adコンポーネントで表示可能です。仕様によると対応しているのは、下記の5つってことですかね。

  • A9
  • AdReactor
  • AdSense
  • AdTech
  • Doubleclick
via a amphtml/amp-ad.md at master · ampproject/amphtml on Github
記述サンプル
<amp-ad width="300" height="250"
        type="adsense"
        data-ad-client="ca-pub-8719035313519225"
        data-ad-slot="8182561962">
</amp-ad>

こちらもlazyloadしてくれます。

amp-pixel

アクセス解析などのログは、非可視なimgでとるオールドスタイル?で、そのための要素がamp-pixelです。src属性に設定するパラメータを$hogehogeが出力してくれるので、使用しているサービスに合わせて記述します。

例えば、下記のようなものがあります。

$RANDOM
ランダム文字列に置換されます。
$CANONICAL_URL
rel="canonical"の値に置き換わります。
$TITLE
ページのタイトルに置き換わります。

Google Analyticsの場合は、記述例がありましたのでそちらを参考にしました。

Use Google Analytics in AMP HTML

検証

うまくAMP HTMLに則って記述できているかどうかですが、URLの末尾に "#development=1" を付与してアクセスすると、開発者ツールのConsoleに検証結果を吐いてくれます。

このブログの検証結果。Chrome開発者ツールのConsoleにAMP valication successful.の記載がある

まとめ

思い立ってやってみましたが、もともとが静的なページなので対応すること自体はCMSの出力設定を変えたりするだけですので、それほど手間はかからないように感じました。

ただし、通常ページとAMP HTMLで分ける形ですと、CSSや広告コードが分離してしまうので、運用の負荷は高くなりそうです。

このブログもシンタックスハイライト以外の必要な機能はほとんど置き換えられそうなので、日本でのプラットフォームの対応状況によっては完全に移行することもアリなのかもしれませんが、おそらくそのうち面倒になってAMP HTML側の方をメンテしなくなるのに3000点です。