RailsサイトのAMP化をしていたところ、ルーティング等の面倒くさい設定が完了し、まずはとりあえず「AMP HTML」のサンプルと同じAMPページを作って出力してみたら、サンプルと同じはずなのにAMPバリデートエラーが生じてしまいました。
調査するとRailsでAMP化するとき特有ともいえる、gemによって発生していたものでしたので、内容と対処法をまとめておきます。
AMP HTMLサンプルテンプレート
https://www.ampproject.org/ja/docs/reference/spec#sample-document
こちらのAMPプロジェクト公式のAMP HTMLサンプルテンプレートを利用して、とりあえずAMPページとして出力しようとしておりました。
※ややこしい amp-img
タグと amp-ad
タグの部分は削除してあります。
<!doctype html>
<html ⚡>
<head>
<meta charset="utf-8">
<title>Sample document</title>
<link rel="canonical" href="./regular-html-version.html">
<meta name="viewport" content="width=device-width,minimum-scale=1,initial-scale=1">
<style amp-custom>
h1 {color: red}
</style>
<script type="application/ld+json">
{
"@context": "http://schema.org",
"@type": "NewsArticle",
"headline": "Article headline",
"image": [
"thumbnail1.jpg"
],
"datePublished": "2015-02-05T08:00:00+08:00"
}
</script>
<script async custom-element="amp-carousel" src="https://cdn.ampproject.org/v0/amp-carousel-0.1.js"></script>
<style amp-boilerplate>body{-webkit-animation:-amp-start 8s steps(1,end) 0s 1 normal both;-moz-animation:-amp-start 8s steps(1,end) 0s 1 normal both;-ms-animation:-amp-start 8s steps(1,end) 0s 1 normal both;animation:-amp-start 8s steps(1,end) 0s 1 normal both}@-webkit-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-moz-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-ms-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-o-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}</style><noscript><style amp-boilerplate>body{-webkit-animation:none;-moz-animation:none;-ms-animation:none;animation:none}</style></noscript>
<script async src="https://cdn.ampproject.org/v0.js"></script>
</head>
<body>
<h1>Sample document</h1>
<p>
Some text
</p>
</body>
</html>
AMPに必須なものだけの、本当にミニマムなAMP HTMLです。
サンプル通りなのにバリデートエラー
表示されているページが、ちゃんとAMP HTMLになっているかどうかをチェックするAMPバリデーターはChrome DevToolに標準で搭載されています。
URL末尾に #development=1
をつけてページを開き、Chrome DevToolのConsoleで確認できます。
するとサンプルテンプレート通りに作ったにも関わらずエラーが発生しました。
Only AMP runtime 'script' tags are allowed, and only in the document head
とあります。
AMPでは、AMP提供のものと「application/ld+json」形式以外のJavaScriptは使用できないことになっています。
それを守っていないよというエラーだと思うのですが、ただサンプルテンプレートのコピペしただけなのになぜ?
出力ページのページソースを直接確認
いつものブラウザの「ページのソースを表示」から。
<!doctype html>
<html ⚡>
<head>
<meta charset="utf-8">
<title>Sample document</title>
<link rel="canonical" href="./regular-html-version.html">
<meta name="viewport" content="width=device-width,minimum-scale=1,initial-scale=1">
<style amp-custom>
h1 {color: red}
</style>
<script type="application/ld+json">
{
"@context": "http://schema.org",
"@type": "NewsArticle",
"headline": "Article headline",
"image": [
"thumbnail1.jpg"
],
"datePublished": "2015-02-05T08:00:00+08:00"
}
</script>
<script async custom-element="amp-carousel" src="https://cdn.ampproject.org/v0/amp-carousel-0.1.js"></script>
<style amp-boilerplate>body{-webkit-animation:-amp-start 8s steps(1,end) 0s 1 normal both;-moz-animation:-amp-start 8s steps(1,end) 0s 1 normal both;-ms-animation:-amp-start 8s steps(1,end) 0s 1 normal both;animation:-amp-start 8s steps(1,end) 0s 1 normal both}@-webkit-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-moz-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-ms-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-o-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}</style><noscript><style amp-boilerplate>body{-webkit-animation:none;-moz-animation:none;-ms-animation:none;animation:none}</style></noscript>
<script async src="https://cdn.ampproject.org/v0.js"></script>
</head>
<body>
<h1>Sample document</h1>
<p>
Some text
</p>
<script async type="text/javascript" id="mini-profiler" src="/mini-profiler-resources/includes.js?v=9db1f8db18400644bd5c7449e5295620" data-version="9db1f8db18400644bd5c7449e5295620" data-path="/mini-profiler-resources/" data-current-id="do6ge3kdg5exsbbphsap" data-ids="do6ge3kdg5exsbbphsap,fc9hgke1ptxn3vb0sviy,tepcmq0wjhn0njfwofu5,kpd5c9tum1022gh3vo4,75ocdzxnyt0phb1mo7mi,s5ijv1gq9e5yu1iewe5p,135tooj4i31nt4l9nlzq,7tuev8odugmnmahar4tt,rjwiec8j6yxqa8flhv6t,1guinsgu8i3ej963avbr" data-position="left" data-trivial="false" data-children="false" data-max-traces="10" data-controls="false" data-authorized="true" data-toggle-shortcut="Alt+P" data-start-hidden="true"></script>
</body>
</html>
</body>
の直前に知らないscriptタグがある。
<script async type="text/javascript" id="mini-profiler" src="/mini-profiler-resources/includes.js?v=9db1f8db18400644bd5c7449e5295620" data-version="9db1f8db18400644bd5c7449e5295620" data-path="/mini-profiler-resources/" data-current-id="do6ge3kdg5exsbbphsap" data-ids="do6ge3kdg5exsbbphsap,fc9hgke1ptxn3vb0sviy,tepcmq0wjhn0njfwofu5,kpd5c9tum1022gh3vo4,75ocdzxnyt0phb1mo7mi,s5ijv1gq9e5yu1iewe5p,135tooj4i31nt4l9nlzq,7tuev8odugmnmahar4tt,rjwiec8j6yxqa8flhv6t,1guinsgu8i3ej963avbr" data-position="left" data-trivial="false" data-children="false" data-max-traces="10" data-controls="false" data-authorized="true" data-toggle-shortcut="Alt+P" data-start-hidden="true"></script>
これがどこからやってきたのかというと、正体は rack-mini-profiler
というViewのレンダリングやDBクエリのパフォーマンスを計測して表示してくれるgemが発行しているものだった。
こんな感じで計測時間をブラウザの左上に表示してくれる、普段は便利なやつです。
対策
gemをOFFにしたりマスキング的なことしないとかなと思いましたが、幸い rack-mini-profiler
はURL操作のみで計測結果を表示しないようにすることができました。
URLにパラメータ?pp=disable
をつけるだけで、同一セッション内で計測結果が常に表示されなくなり、今回のエラー対象のスクリプトも発行されなくなります。
http://hoge.com/articles/1.amp?pp=disable
再度、計測結果を表示するようにするためには、URLにパラメータ?pp=enable
をつければ大丈夫です。
結果
Consoleで確認するとエラーが消え、AMP validation successful.
と表示され、無事にAMPページとして認識されました。
まとめ
AMPではJavaScriptやCSSの使用に制限があります。
Railsのgemのなかには、gem側でJavaScriptやCSSを発行するものも存在するので、AMP対応には注意が必要です。
今回は rack-mini-profiler
というgemが対象でしたが、有名どころだとN+1問題を検出し表示してくれる bullet なんかも同じことが起きると思います。
本番環境では起きなかったりするものも多いかと思いますが、適宜gemの無効化や設定変更がAMP対応には必要になってきそうです。