at posts/single.html

tDiaryをAMP対応させモバイル表示を高速化した

最近、Google検索やはてなブックマークでAMPという技術が導入されている。AMPはモバイルでの表示速度を高速化するための仕様で、最初はニュースサイトから採用が始まっていた。この秋頃から、一般サイトの検索結果にもAMP対応サイトが表示されるようになってきたので、tDiaryもAMPに対応させてみた。

この日記も数日前からAMPを導入していて、ようやくGoogleの検索結果にも反映されるようになった。スマートフォンでbrowsereidと検索すると、このように検索結果に⚡AMPマークが表示される。

tDiary AMP support

特にモバイル環境で試してみると分かるけど、AMP対応ページは一瞬で表示される。

AMP対応ページが高速に表示される仕組み

AMPでは、ページを高速化するためにいくつかの工夫と制約をかけている。AMPの公式ページに書かれているように、非同期のスクリプトのみ許可したり、スタイルシートを埋め込んだり、標準のHTMLに比べてできることをかなり制限している。さらに、コンテンツをCDNでキャッシュすることで、低遅延での配送を可能にしている。

tDiaryもAMP対応してみた

AMPはその制約上、静的なページに向いている。tDiaryはうってつけだろうと思い、AMP対応のプラグインを書いた。

設計の基本方針として、既存のHTMLをAMP向けにカスタマイズするか、それともAMP専用ページを作るかの2案がある。AMPはまだ仕様が変わりそうなのと、制約が多く元ページを完全再現するのは難しいだろうと判断し、AMP専用ページを作ることにした。

AMPはtDiaryのプラグインとして実装する。プラグインでは専用のコンテンツを返すための add_content_proc という仕組みがあるので、それを使う。既存ページに ?plugin=amp を付けるとAMPページが表示されるようにした。tDiaryの特徴であるセクションアンカーが反映されないけど、これはもう仕方ない。

  • 既存ページ: http://www.machu.jp/diary/20110722.html
  • AMP対応ページ: http://www.machu.jp/diary/20110722.html?plugin=amp

misc/plugin/amp.rbをつくり、以下の処理を書く。

add_content_proc('amp') do |date|
  diary = @diaries[date]
  ERB.new(File.read("views/amp.rhtml")).result(binding)
end

views/amp.rhtmlはAMP公式サイトのチュートリアルを見ながら雛形を作っていく。

<!doctype html>
<html ⚡ lang="ja">
  <head>
    <meta charset="utf-8">
    <script async src="https://cdn.ampproject.org/v0.js"></script>
    <title><%= amp_title %></title>
    <link rel="canonical" href="<%= amp_canonical_url(diary) %>" />
    <meta name="viewport" content="width=device-width,minimum-scale=1,initial-scale=1">
    <script type="application/ld+json">
      {
        "@context": "http://schema.org",
        "@type": "BlogPosting",
        "headline": "<%= amp_headline(diary) %>",
        "datePublished": "<%= amp_last_modified(diary) %>",
        "dateModified": "<%= amp_last_modified(diary) %>",
        "image": [
          "<%= amp_logo %>"
        ],
        "description": "<%= amp_description(diary) %>"
      }
    </script>
    <style amp-boilerplate>中略</style></noscript>
    <style amp-custom>
    <%= amp_style %>
    </style>
  </head>
  <body>
    <div class="whole-content">
      <div class="adminmenu">
        <%= navi_user %>
      </div>
      <div class="content">
        <h1><a href="<%= amp_canonical_url(diary) %>"><%= amp_title %></a></h1>
        <div class="day">
          <h2><%= amp_day_title(diary) %></h2>
          <div class="body">
            <%= amp_body(diary) %>
          </div>
        </div>
      </div>
      <div class="footer">
      </div>
    </div>
  </body>
</html>

あとは、HTMLに埋め込みたいデータをプラグイン側でちょこちょこ書いていくだけ。

  • スタイルシートはHTMLに埋め込まないと使えないので、プラグイン側でFile.readして埋め込んでいる
  • img要素は使えないのでamp-img要素に置き換えている

まだまだ基本だけだけど、これで一通り動くようになった。

まだYouTubeなどの埋め込み系には対応できていない。Google Search Controlを使えば、どのページがAMPとして非対応なのかを教えてくれるので、それを見ながら修正していくつもり。これはボチボチやっていこう。

tDiaryをお使いの方は、ぜひAMPプラグインを導入してフィードバックいただければ。

関連する日記