農機具業界初?ページをAMP化した際のポイント

みなさん
お久しぶりです。

制作/ブランディングユニットのナカマです。

みなさんAMPはご存知でしょうか?

AMPはgoogleが導入を進めているモバイル端末でのページの表示高速化プロジェクトです。
最近は導入されているページも増えてきているので
認知度としてはかなり上がってきているのではないでしょうか。

具体的には下記のあたりを参考にしていただければと思います。

今回弊社サイト農機具高く売れるドットコムのページをAMP化する機会がありましたので
ポイントをまとめておきたいと思います。
以下が今回AMP化する既存のページです。

トラクター買取

AMPには各種の制限事項があります。
速度改善を主目的としている為、レンダリングの再計算や
レンダリングをブロックするような要素を極力排する為の対応です。
大きな制限としては

  • 一部タグの禁止とカスタムタグの利用
  • 外部jsの禁止
  • 外部cssの禁止

などが挙げられます。

今回のように既存のページがすでに存在している場合
わかりやすく一番ネックになってくるのは外部js・cssの禁止でしょう。
jQueryや他ライブラリを使用して作成されたページの場合、実装する機能の取捨選択が必要になります。

しかし最近AMPページもできることが増えてきていて、
下記ページに新しいコンポーネントなどが逐次まとめられています。
AMP by Example:component
また、まだexperimental(実験)段階ではありますが
インタラクティブな動作を可能にするamp-bindと言う機能も出てきています。

これらを駆使すれば現在jsで実装されている機能についても
実現できる可能性が広がっていくかと思います。

amp-bindについて

今回のページでは実装していませんが、一部実装時につまづきそうな点があったので
補足しておきます。

  • 1:amp-stateの宣言が必須

    <amp-state>の宣言が必須になります。
    JSON形式で記述します。

  • 2.bindの書き方が少し特殊

    ボタンクリックイベントなどでバインドする場合の書き方に少し注意が必要です。
    コード例を以下に示します。
    このコードはbuttonタグをクリックした場合にpタグの中のテキストが変わる処理です。

    • <amp-state id="myState">内でbindするデータをJSON形式で記述します。
    • [text]="'Hello ' + myState.foo"でstateのどの要素にbindするかを宣言します。
      その際にデフォルトの値については予め記述しておきます。(この場合はHello barのbarの部分)
    • on="tap:AMP.setState({myState: {foo : 'bind'}})"でbuttonタグがクリックされた時にどう変わるかを記述します。
      setStateの部分で予め宣言したamp-stateのid(この場合はid=myState)を記述し、
      その中のプロパティに関してどう変更するのかを記述します。
      この場合はpタグの中のbar → bindに変更しています。
    • より良い書き方があるかもしれませんが、このような形で実現は可能です。
      さらに詳細な例はAMP by Example:amp-bindを参考していただければと思います。
      Reactを触っている方はstateの管理など、イメージ的に近いものがあるかもしれません。

方針を立てる

今回に関しては既存のソースが存在しているので
どのような流れで既存コードをAMP対応にしていくのか方針を立てます。
今回作業したページに関しては

  • タグの置き換え
  • 外部jsの削除や外部cssのインライン化
  • 実装する機能の取捨選択
  • デバッグ

の順で進めていきます。

タグの置き換え

まずはタグの置き換えです
<img>タグを<amp-img>タグに変換していきます。

ここでもいくつか注意点があります。

サイズの入力が必須

ampページでは全ての画像にwidthとheightを事前に入れておくことが義務付けられています。
画像読み込み後のレイアウトの再計算を防ぐためです。
レイアウトの再計算に関しては理解しておくとページのチューニングの際に有効です。

なおスマホページの場合は当然レスポンシブ対応をされているページもあるかと思います。
その場合はlayout="responsive"をタグ内に記載すると
指定した画像のアスペクト比を維持したままウィンドウサイズで拡大縮小します。

なおその際にlayout="responsive"を指定した画像については自動的に横幅いっぱいに広がるので
floatなどでwidthを指定したい場合はwrapしたタグにwidthを指定するなどの工程が必要です。

タグの構造が変わる

<img>タグについては<amp-img>に置き換わる時に階層構造が変化します。
以下タグの例です。

・元のタグ

・AMPのタグ(出力前)

・AMPのタグ(出力後)

ご覧の通り タグに
タグがwrapされた状態で出力されます。
ですので

などと記載している場合はスタイルが正しくあたらなくなることがあります。
画像などで表示が崩れる場合はこの辺りを疑うといいでしょう。

外部jsの削除や外部cssのインライン化

外部から読み込まれるjsはAMP対応の一部のjs以外は許容されていません。
ですので既存の外部jsを削除して、使用しているcssに関してはインライン化をします。

またその際にcssについては
50KBまでに削減する必要があり、
使用できるスタイルに関しても
一部制限があります。

前者について削減する必要のあるcssの特定には
chrome59から登場したcoverage機能などを利用するのもいいかもしれません。
※なおその際に必要/不必要は開いているページでのみ判断されますので
共通で読み込まれているcssについてはスタイルをむやみに削除しないよう注意しなくてはなりません。

実装する機能の取捨選択

今回のページでは以下のような動作がjsに依存していました。

  • メニューはメニューアイコンをタップした場合のみ表示
  • メニュー内のアコーディオン表示
  • Topへ戻るボタン

それぞれを下記のような形で実装しました。

それぞれ完全に元の機能の再現ができていない部分もありますが、
割り切って実装していきます。
AMP化する場合は完璧な再現はしようとせず
AMPでできることに寄せていくイメージの方が実装はしやすいかと思います。

デバッグ

作成したページのurlに#development=1をつけると検証ツールが立ち上がるので
出力されるエラーを一つ一つ修正していきます。
各種エラーコードに関しては以下のページなどを参考に修正を進めていきます。
AMPの基本

作業結果

完成したページがこちらになります。
トラクター買取(AMP対応)

googleのdevtoolでネットワーク環境を設定し、
擬似的にテストした際の読み込み速度はそれぞれ以下のようになりました。

【Regular3G】
既存:15.31s
AMP:3.96s
【Regular4G】
既存:3.27s
AMP:1.31s

AMPについては通信環境が悪い場合ほど効果が顕著に見られます。
一部海外や3G回線の地域では当然ですが、
それに関わらず遅くなるタイミングや場所は存在するのでAMP対応を進める意味はあると感じます。

今後について

既存のページ以外にAMP用のページを作成する場合は当然ページ数が増える形になります。
更新・修正する工数を考えると管理するページが増えるのは好ましくないかと思うので
そのような場合に備えて、phpなどで自動的にタグを置き換えるような形での実装を考えています。

また今回は触れませんでしたがGoogleAnalyticsなどトラッキング周りについても
AMP独自のタグを設置することになるので、
タグを設置しているページは注意して頂いた方が良いかと思います。

キャッシュされる関係上cookieなどのやり取りに関しては一部気になる点もありますが
対応を進めて行って損はないかと考えています。
もちろんページスピードが上がること自体、UXの改善に大きく寄与するので
ユーザー目線としても対応していく価値はあるかと思います。

またECサイトなどにも事例が出始めているようなので、
今後はより広がっていくのではないでしょうか

付録:AMP-example内の使いそうなもの