こんにちは、akiyamaです。
先日、いこーよの記事をAMP(Accelerated Mobile Pages)化しました。 AMP化にあたりいくつか知見が得られましたのでご紹介します。
AMPとは
AMPはAMP Projectで策定されているモバイルページ高速化の仕組みです。 AMP HTML仕様に沿ったページを作成することによって、モバイル端末での表示パフォーマンスの高速化が期待できます。
AMPの仕様は日本語の情報がSEO関係のページに出回っています。 わりと古めの情報などもありますので、ちゃんとampprojectの一次情報を参照するほうが確実です。
ampbyexampleは実際に動くものが書かれているので便利でした。
AMP化
通常のHTMLをAMP化するためには、次のものが必要です。
<!doctype html>
で開始html
タグを<html amp>
にするhead
タグの最初の子タグに<meta charset="utf-8">
を書く<link rel="canonical" href="" />
で元記事のURLを指定する- viewportを定義:
<meta name="viewport" content="width=device-width,minimum-scale=1">
- AMP用JSを読み込み:
<script async src="https://cdn.ampproject.org/v0.js"></script>
- head内にスタイルを定義
<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>
また、AMP規格ではありませんが、google用に構造化データをhead
内に書くことが多いと思います。
いこーよの記事ではJSON-LDで記載しています。この内容はページに合わせて変える必要があります。
<script type="application/ld+json">
{
"@context":"http://schema.org",
"@type":"NewsArticle",
"mainEntityOfPage":"http://iko-yo.net/articles/1671",
"headline":"親子向け体験コンサート",
"datePublished":"2016-09-12T03:24:24Z",
"dateModified":"2016-09-12T03:24:24Z",
"description":"開館30周年を迎えた...",
"author":{"@type":"Person","name":"坪内 智子"},
"publisher":{"@type":"Organization","name":"子供とお出かけ情報「いこーよ」",
"logo":{
"@type":"ImageObject",
"url":"http://iko-yo.net/images/iko-yo_logo_290_50.png",
"width":290,
"height":50
}
},
"image":{
"@type":"ImageObject",
"url":"http://d2goguvysdoarq.cloudfront.net/system/article_assets/attachments/1812/original.jpg?1473650664",
"width":640,
"height":426
}
}
</script>
JSON-LDで指定するlogo
とimage
(サムネイル画像)にはガイドラインがあります。これについては次の画像の説明で触れます。
これでAMPの枠組みが出来ましたので、body
内で通常HTMLから変更が必要な箇所についてやったことなどを書いていきます。
(AMP拡張タグに必要なjavascriptファイルの読み込みなどは冗長なので省略しています)
画像
AMPではimg
タグをamp-img
に置き換えたうえ、属性に画像サイズを必ず指定しなければなりません。
いこーよの記事画像はサイズを持っていないため、そのままではAMP化できませんでした。
AMPページをレンダリングするたびに画像サイズを取得するのは、 サイトの負荷を考えると避けたいと考えたため、 今回は記事作成時に画像サイズを保存するように改修しました。
(そのため、過去に作成された記事のAMP化は見送っています)
記事に使われる画像は、内部でアップロードされるものと、外部画像をそのまま使用するものがあります。
外部画像サイズの取得は、アップロード時にJavaScript(CoffeeScript)からImageオブジェクトを作成して取得、
geometry: (src)->
img = new Image
img.src = src
width = img.width
height = img.height
...
内部画像はpaperclipでリサイズされるため、paperclip-metaを使用しています。
サムネイル
AMP化したページはgoogleの検索結果に表示されることがあります。
サムネイルとして表示される画像は、JSON-LDで指定するimage
が対応します。
"image": {
"@type": "ImageObject",
"url": "https://example.com/thumbnail1.jpg",
"height": 800,
"width": 800
},
その際表示される画像は横幅696px以上でなければならないとあります。
The representative image of the article. Only a marked-up image that directly belongs to the article should be specified.
Images should be at least 696 pixels wide. Images should be in .jpg, .png, or. gif format. Image URLs should be crawlable and indexable.
https://developers.google.com/search/docs/data-types/articles#type_definitions
いこーよの場合、サムネイル画像がサイズ要件を満たさないことがあるため、そのような記事ではgoogle検索結果への表示は期待できないかもしれません。
またロゴについても上記ページ内でガイドラインがあります。これは長くなりますのでガイドラインを参照ください。
iframe
いこーよの記事では埋め込みコンテンツとして、google map, youtube, instagramを使用しています。
(instagramはiframe src='http://instagram.com/p/.../embed'
形式)
このうち、google map, youtubeはiframe
をそのままamp-iframe
に置き換えています。
amp-youtube
などの専用の拡張タグがありますが、実装上AMPではない記事本文を流用しやすいamp-iframe
を採用しました。
ただし、google map, youtubeを正常動作させるためには、sandbox="allow-scripts allow-same-origin"
の指定が必要でした。
この指定ではsandboxがあまり意味を成さないため、専用タグの方がやはり適切かもしれません。
また、amp-iframe
はplaceholderとしてamp-img
を子要素にもつ必要があります。
当初はinstagramもiframe
の使用を考えていましたが、amp-iframe
で埋め込んだ場合、一部リンクが開けなくなってしまいました。
そのためinstagramはamp-instagram
拡張タグを使用して埋め込んでいます。
instagramのframeサイズは画像サイズに依存するため、正方形と長方形の画像で異なります。
正方形ならwidth="1" height="1"
と適当な固定サイズの指定が可能ですが、正方形以外はきちんとサイズを指定しないといけません。
https://ampbyexample.com/components/amp-instagram/
SNS
twitter, facebookなどSNSの共有ボタンはamp-social-share
で作成可能です。
他のAMPサイトを見るとamp-social-share
を使用しているケースはあまりなく、a
タグを使っていることが多かったです。
今回はAMPらしくamp-social-share
を使用して実装しました。
twitter, facebookはpre-configured providersに含まれるので、そのまま使用できます。
(facebookはdata-param-app_id
の設定が必要です)
設定されていないSNSを使用する場合は、data-share-endpoint
を使用して設定します。
lineの場合、data-share-endpoint='http://line.me/R/msg/text/?{パーセントエンコードされたテキスト}'
と指定することでシェアボタンが使えるようになります。
endpointにline://msg/text/
のようなプロトコルを指定すると、後述するバリデーターに怒られます。
使用できるプロトコルはホワイトリスト化されているものだけになります。
name: "data-share-endpoint"
value_url: {
allowed_protocol: "ftp"
allowed_protocol: "http"
allowed_protocol: "https"
allowed_protocol: "mailto"
# Whitelisting additional commonly observed third party
# protocols which should be safe
allowed_protocol: "fb-messenger"
allowed_protocol: "skype"
allowed_protocol: "snapchat"
allowed_protocol: "sms"
allowed_protocol: "tel"
allowed_protocol: "viber"
allowed_protocol: "whatsapp"
allow_relative: false
}
広告
いまいち安定せず、出なかったりすることがあります。 広告業者によっても違うようです。 これについてはまだ調査中です。
javascript
AMPページ内では基本的にjavascriptが使用できません。 いこーよの記事内ではそれほどjavascriptを使用していなかったため大きな問題にはなりませんでした。
動的なコンテンツに対応する場合はamp-list
などの拡張タグを使用する必要があります。
現時点では動的なAMPページをつくるメリットはあまり無いと思います。
バリデーション
作ったAMPページが正しいかチェックするためのバリデーションには https://www.ampproject.org/ja/docs/guides/validate.html で紹介されているブラウザ拡張が便利でした。
バリデーションだけでなく、<link href="/articles/1666/amp" rel="amphtml">
とAMPページヘのリンクがあるページでは、機能拡張ボタンからAMPページヘ移動できます。
まとめ
いこーよの記事ページのAMP化を行いました。
特に画像やiframe
のサイズ周りの対応に気を使う必要がありました。
それ以外の部分ではあまり手もかからず通常HTMから変換が可能でした。
AMPページの制限は大きいので、あまり凝ったことはせずに、 まずはシンプルなAMPページ化していくのが良いのではないかと思います。