RailsでAMP化するときにエラーがでたらgemも疑う

RailsサイトのAMP化をしていたところ、ルーティング等の面倒くさい設定が完了し、まずはとりあえず「[AMP HTML](https://www.ampproject.org/ja/docs/reference/spec)」のサンプルと同じ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`タグの部分は削除してあります。

```html
<!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で確認できます。

するとサンプルテンプレート通りに作ったにも関わらずエラーが発生しました。

<img width="984" alt="１.png" src="https://qiita-image-store.s3.amazonaws.com/0/68751/9e4e716e-87c4-0172-2835-3cf8b939f384.png">

> `Only AMP runtime 'script' tags are allowed, and only in the document head`

とあります。

AMPでは、AMP提供のものと「application/ld+json」形式以外のJavaScriptは使用できないことになっています。
それを守っていないよというエラーだと思うのですが、ただサンプルテンプレートのコピペしただけなのになぜ？


### 出力ページのページソースを直接確認

いつものブラウザの「ページのソースを表示」から。

```html
<!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タグがある。

```html
<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](https://github.com/MiniProfiler/rack-mini-profiler)が発行しているものだった。

<img width="986" alt="2.png" src="https://qiita-image-store.s3.amazonaws.com/0/68751/98bf981d-9988-4acf-3e8e-b3083ac067f7.png">

こんな感じで計測時間をブラウザの左上に表示してくれる、普段は便利なやつです。

## 対策
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ページとして認識されました。

<img width="987" alt="3.png" src="https://qiita-image-store.s3.amazonaws.com/0/68751/e3569be1-8156-f4c6-2be7-57bbc7f0b3fb.png">

## まとめ
AMPではJavaScriptやCSSの使用に制限があります。
Railsのgemのなかには、gem側でJavaScriptやCSSを発行するものも存在するので、AMP対応には注意が必要です。

今回は `rack-mini-profiler` というgemが対象でしたが、有名どころだとN+1問題を検出し表示してくれる [bullet](https://github.com/flyerhzm/bullet) なんかも同じことが起きると思います。

本番環境では起きなかったりするものも多いかと思いますが、適宜gemの無効化や設定変更がAMP対応には必要になってきそうです。