AMP ざっくりまとめ

AMPについて調べたのでざっくりまとめる。

## AMPとは何か
- AMP（Accelerated Mobile Pages）
- Googleが中心となって立ち上げた、モバイルデバイスでのWebブラウジングを高速化することを目的としたオープンソースプロジェクト
- 従来より用いられているHTMLなどのWeb技術を改良している

## こういうの
![25032cb699de953cc3c958591e372808.gif](https://qiita-image-store.s3.amazonaws.com/0/2813/41e7e9cb-6b92-2496-ce7e-125129d7813a.gif)

上のgifではGoogleで「渋谷 うどん」で検索したのち、AMP対応している食べログのサイトを開いている。
タップすると瞬時に食べログの詳細画面が表示されているのがわかると思う。

AMP対応しているサイトは、以下の画像のように検索結果のリストにAMPマークが表示されている。
![Screen Shot 2017-07-02 at 14.24.58.png](https://qiita-image-store.s3.amazonaws.com/0/2813/25944c9b-154f-3027-0546-1112d011ca4f.png)

## 適しているサイト
どんなページでも高速化するわけではなく、適したサイトが決まっている。
以下、『[Real World HTTP](https://www.oreilly.co.jp/books/9784873118048/)』の第8章より引用。

> AMPは、あらゆるタイプの静的なウェブ コンテンツ（ニュース、レシピ、映画情報、製品ページ、レビュー、動画、ブログなど）で大きな効果を発揮します。
> 一方、動的で双方向性を重視した単一のページのサービス（地図の経路案内、メール、ソーシャルネットワークなど）にはあまり効果的ではありません。

## AMP化するには
AMP HTML、AMP JSというを使ってページを作成するだけで良い。
そのようにしてAMPのルールに則って構築されたサイトは、Googleのクローラーや配信用キャッシュサーバもAMP専用の動作をし、高速化される。

[AMP HTMLページを作成する](https://www.ampproject.org/ja/docs/tutorials/create/basic_markup)というチュートリアルページには、AMP HTMLが満たすべき条件として次のような項目が挙げられていた（抜粋）。

- `<!doctype html>`という文書型宣言で開始する
- 最上位階層のタグを`<html ⚡>`（`<html amp>`でも可）にする
- ヘッド部に`<link rel="canonical" href="$SOME_URL" />`タグを入れて、AMP HTML版の通常のHTMLバージョンを指定する。該当するHTMLが存在しない場合は自身を指定する。
- headタグの最初の子要素を`<meta charset="utf-8">`タグにする

## AMPを構成する3つのコアコンポーネント
AMPは、大きくAMP HTML、AMP JS、AMP Cacheの3コンポーネントから構成される。

https://www.ampproject.org/ja/learn/overview/　から

- **AMP HTML**
  - パフォーマンスを保証するための制約が設けられたHTML
  - 通常のHTMLより優れたリッチコンテンツを作成できる拡張機能が備わっている
  - ほとんどは通常のHTMLタグだが、一部のHTMLタグはAMP専用のタグになる
  - これらのカスタム要素はAMP HTMLコンポーネントと呼ばれ、このコンポーネントを使うとハイパフォーマンスな共通のパターンを簡単に実装できる
      - 例：`amp-img`タグ、`amp-video`タグ

- **AMP JS**
  - AMP HTMLページのレンダリングを高速化するのが、AMP JSライブラリ
  - AMP JSライブラリに、AMPのパフォーマンス最適化処理がすべて実装されている
  - 重要な最適化処理の1つが、外部リソースからの読み込みを完全に非同期にすること。これによりページ内の要素がレンダリング処理をブロックすることはなくなる

- **AMP Cache**
  - Google AMP Cacheは必要に応じてAMP HTMLページを配信する
  - この機能を使用すると、HTTP2.0を使っている共通の場所からドキュメントや全てのJSファイル、イメージを読み込む

## AMPによるパフォーマンス改善の仕組み

https://www.ampproject.org/ja/learn/about-how/ から。

- **非同期スクリプトのみ使用を許可する**
  - JavaScriptがページのレンダリングを遅らせてしまう場合がある。これを防ぐため、AMPでは非同期のJavaScriptのみ使用を許可している
  - インタラクティブなページ機能は、JSの代わりにカスタムAMP要素をつかう
  - サードパーティのJSはiframe内で使用可能となっていて、レンダリングの妨げにはならない

- **全てのリソースサイズを静的に決定する**

- **拡張機能によるレンダリングブロックを回避する**
  - ライトボックス、Instagramの埋め込み、ツイートの埋め込みなどといった拡張機能がレンダリングをブロックしないようにする

- **サードパーティのJavaScriptを全てクリティカルパスから外す**
  - AMPページではサンドボックス化されたiframe内でのみ、サードパーティのJSを使用できる
  - iframe内に制限することで、メインページの実行をブロックさせないようにしている

- **CSSは全てインラインスタイルにしてサイズを固定する**
  - CSSはページの読み込みやレンダリングをブロックすることがある
  - AMP HTMLページではCSSをインラインスタイルで記述することで、HTTPリクエストをクリティカルレンダリングパスから削除する

- **フォントのトリガーを効率化する**
  - Webフォントはサイズが非常に大きく、パフォーマンスに大きな影響を与える
  - これまでの典型的なページでは、CSSやJSの全てを処理するまで、ブラウザはサイズの大きいフォントのダウンロードを開始できなかった
  - AMPシステムのJSには全て非同期属性があるため、フォントのダウンロードをブロックするHTTPリクエストが発生しない

- **できるだけスタイルを再計算しない**
  - AMPページでは描画処理を始める前に DOM を全て読み込む
  - これにより、1フレームあたりのスタイル再計算は最大でも1回になる

- **GPUアクセラレーションが有効なアニメーションのみ実行する**

- **リソースの読み込みに優先順位をつける**
  - AMPはあらゆるリソースのダウンロードを制御し、読み込むリソースの優先順位付けを行っている。具体的には必要なものだけ読み込み、遅延読み込みされるリソースはプリフェッチする

- **ページを瞬時に読みこむ**
  - AMPでは新しい preconnect API を活用してHTTPリクエストを最大限に高速化している
  - その結果、ユーザがページを開く前にそのページをレンダリングできる。場合によってはユーザが実際にページを選択した時点でページが既に利用可能になっている。
  - プリレンダリングは全てのWebコンテンツに適用できるが、帯域幅とCPUを多く消費する。AMPはこれらの消費を抑えるように最適化されている。
    - プリレンダリングによってダウンロードされるのは、スクロールせずに見える範囲にあるリソースのみにする。CPUを多く使うものは事前にレンダリングしない

## AMPの設計方針・思想

https://www.ampproject.org/ja/learn/amp-design-principles/ から

- **ユーザ体験（UX） > 開発者体験（DX） > 実装の容易さ**
  - ページ作成者やライブラリ開発者にとって難しい場合でも、エンドユーザの体験にとって最善のものを選択する

- **将来のブラウザを想定しない**
  - 将来ではなく今現在のweb・ブラウザにおいて、高速化できるものを選択し、開発する
  - 今現在のWebにおいて最適化が困難な場合は、AMP開発者はそれを実現するためにWeb標準の開発に参加すべきである

- **Webを壊さない**
  - AMPに問題があったとしても、Webの残りの部分を壊さない
  - AMP Cacheで動くものは、AMP Cacheが存在しなくても正しく動作するべきである

- **正しいレイヤで問題を解決する**
  - 例：サーバ側で対処すべき問題を、より簡単であるという理由だけでクライアント側で解決しようとしない（逆も同様）
  
- **高速化に寄与するもののみ行う**
  - 現在の一般的な環境で確実に動作しないものをAMPに導入しない
  - 例えば、現在のモバイルデバイスでは60fpsで確実に動作する必要がある

- **ユーザ体験が向上するものを優先するが、必要に応じて妥協する**
  - AMPは素晴らしいユーザ体験を届けるが、スピードはユーザ体験の一部にすぎない
  - 何かをサポートしていないことでAMPが広く使われなくなってしまう場合のみ、妥協をする

- **ホワイトリストは存在しない**
  - セキュリティやパフォーマンス上の理由から必要な場合を除き、特定のサイトやドメインを特別扱いすることはない

## AMPを調べての所感
- AMPの提供するユーザ体験は素晴らしく、要件が合うならば対応すべきだと思う
- エンドユーザとしては非常に嬉しい
- 感覚値だがMVNOの通信速度は3大キャリアと比べるとやはり遅く、特に電車内など混雑した環境ではかなり厳しいときがある。そういった時、自分ならばAMP対応したサイトを優先的に閲覧しようとすると思う。
- チュートリアルをやったレベルでの感想ではあるが、AMP対応は大変ではない。少なくとも得られる恩恵の方が大きいと思う
- AMP用と非AMP用のページを用意する必要があるようで、メンテナンス性が落ちないかは少し不安。特に、大きなサイトやコンテンツを大量に含むサイトを運営している場合。