うな(。・ε・。)

Android, iOS, AppEngine まわりのめもめも

かんたんな変調・復調を実装してみる

超音波通信を実装してみたくて、もっともカンタンに実装できる方法を調査してみました。

もっとも単純な方法で、ノイズがのってもいいような伝達手段を考えます。

変調・復調

波形(音波)に情報を載せることを変調、波形から情報を取り出すことを復調といいます。

FSK変調

変調方式の一つです。 一定時間ごとに、低周波と高周波を切り替えます。低周波を0, 高周波を1に割り当てることによりビット列を表すことができます。

振幅にいくらノイズが載ろうが問題ないこと、復調が比較的単純に行えることから、単純な実装をしたいときに使われます。

実装的には、出力サイン波の周波数をビット列に合わせて切り替えるだけなのでカンタンです。(サイン音波を出すのはオーディオでは基本なのでカンタンです)

https://raw.githubusercontent.com/ezefranca/FSK-Arduino-iOS7/master/FSK-Demo/image.png

FSK復調 (FFT)

あまり直感的な方法ではないですが、波形をフーリエ変換にかければ、周波数成分をとりだすことができます。つまり、どんな周波数が波形に乗っているかがわかります。

ですから、一定時間ごとに波形をフーリエ変換にかけてやり、もっとも大きい周波数成分が低周波、高周波のどちらに近いかを判定することで、その時間帯のビットを取り出してやることができます。 この方法の利点はいくら低周波帯にノイズが乗ろうがまったく無視することができることです。

フーリエ変換FFT という派生アルゴリズムでさまざまな言語に実装されていますので楽チンです。

下図は 16kHz, 18kHz の音波を発生させ、iOS のアプリを用いて FFT しグラフとして表示した結果になります。

f:id:liedderoptik:20151030182155j:plain

16kHz, 18kHz 帯にキレイに線が立っています。低周波帯に環境音のノイズがたくさん乗っていることもわかります。

開始文字・終端文字

どこからどこまでが一つの通信なのかを表すコードを決めておきます。ASCII コードにはそのようなコードがあらかじめ定義されているので、それを用いればいいです。(従って、ビット列は ASCII コードを使って文字列として表すことにします)

  • SOH(x01) = 通信開始
  • EOT(x04) = 通信終了

"Hello" を送るためには次のようなビット列を送ることになります。

01 48 65 6C 6C 6F 04 (文字多くなるため16進数)

FSKの伝送効率

FSKの伝送効率は「一定時間」をいくらとるかによります。一定時間を T と書けば、T 秒ごとに一つのビットが決まるため、1/T [bit/s] が伝送効率になります。

仮に低周波に 18kHz を使い、T としてその 16 周期分をとると、T = 0.000888.. となります。ですから、伝送効率は 1136.4 [bit/s] となり、おおよそ 1 秒に 142 バイトを送ることのできる計算になります。原始的ですね。

FSKの誤差

次の原因で誤差が生じます。

  • いくら周期をとるか
  • 低周波と高周波でいくら周波数の違いがあるか
  • ノイズがのっていないか

誤差をカバーするために通信の最後にチェックサムを付加してやるのがいいと思います。

参考文献

Effective 意識低くコードを書く

あまり多くのことをしたくない、あまり多くのことを覚えたくない、でもちゃんと動くソフトウェアが欲しい。

そんな人がなにを意識してコードを書くべきか、ということを挙げてみました。

変えないのが一番

  • 人は一度に多くの物事を変化させられません / 変化に適応できません。
  • なるべく「変えない」ことを意識してエコシステムを選んだり、システムを設計します。
  • シグネチャはできるなら変えないようにするのが一番です。

抽象化せずに処理をそのまま書く

  • ライブラリを書くのでないかぎり抽象化は要りません。
  • やりたいことを素直にそのまま落とし込んで書くのが一番です。

流れが追えるように書く

  • 流れが追えなければコードがなにをやっているかが掴めません。意図せず飛び地で処理が行われないようにします。
  • 共通処理などが暗黙的に実行されるのもあまりよくないと思っています。各場所で共通処理メソッドを呼んだ方が明示的です。
  • rails の callbacks などの飛び道具は流れをわかりにくくする最たるものです。
  • AOP は幻想です。

理解が難しいものを使わない / 一度にひとつのことしか考えない

  • ひとの脳みそは限りがあるので、なるべく難しいことをしない / 難しいものを使わないようにしましょう。
  • 一度に二つ以上のことを考えるとかならず破綻します。一つ一つ解決していきましょう。

けっきょく人の問題なので、なんでもテクノロジ/規約の問題で解決しようとしない

  • 規約や宣言的プログラミング、共通処理、開発フローで縛るのもいいですが、結局は人の問題です。
  • 開発論的手法で解決出来ることは限られています。結局は人の問題です。
  • 規約や開発フロー、記法といったものはようするに開発者間のテーブルマナーのようなもので、実益はさほどありません。しかしながら、お互いに気持ちよく進めるためにそれらが必要な場面もあります。
  • 開発論的なことや、新しいフレームワークの話、新しいパラダイムの話を聞くと夢が広がりますが幻想です。銀の弾丸はありません。結局コードを書くのは人であって、人の問題です。
  • 人の問題から逃げない。

時間ないけどスプラトゥーンで S+ になる

仕事しながらスプラトゥーンで S+ になるための戦術とか語ります。

ちなみにゲームは好きですがそんなに得意ではありません。FPS は本格的にやったことがありませんし、スプラトゥーンの開発陣が影響を受けたであろうゲーム「ボーダーブレイク」の最高ランクは S1 です。(中くらいのランク)

S+ になってからのランクポイントは 30 付近をうろうろしており、カンストに届く気配はありません。その程度のぱんぴーがとりあえず S+ になるための戦術とかを語ってみようと思います。

ブキはシューターを前提としています。

高ランクになるために大事なこと

  1. AIM と戦闘
  2. 位置取り
  3. 使うブキ

いろいろ大事なことはあると思いますが、上に挙げた三点が最も重視すべきことといえます。

AIM と戦闘

AIM は大事です。AIM がよほど悪ければ完璧に後ろをとっても勝てません。練習しましょう。

といっても超絶 AIM をする必要はなく、自分のブキの射程内で静止した相手にちゃんと当たっていれば十分です。高速で動き回る相手に当て続けるほどの AIM はなくても大丈夫です。

うまく AIM するコツですが、ジャイロはかならず ON にします。ジャイロ無しできちんと AIM するのは難しいです。また、感度はマックスが望ましいです。感度マックスは難しそうに見えますが、マックスにしないと動かなさすぎて逆に難しいと思います。

右スティックで大まかに舵取り&狙いをつけ、Wii U コントローラーを膝で固定し手首だけで細かく動かすようにすれば安定した AIM がしやすいです。

方法さえ間違わなければ AIM はやっているうちになれます。

ジャンプ撃ち

スプラトゥーンでは横移動が遅く設定されています。代わりに、ジャンプ撃ちが強いです。

対面で 1:1 になったときは(特に近距離では)必ずジャンプしながら撃ちましょう。ジャンプボタンは連打するのではなく、しっかり押し続けることが大事です。 なぜ押し続けるかというと、ボタンを押している長さに応じてジャンプの最高高度が変わるからです。

ボタンを連打したときのジャンプは 0.3 キャラほどの高さしかありません。これでは胴体を狙った AIM に当たってしまい、意味をなしません。

ボタンをしっかり押し続けたときのジャンプは 1 キャラ近くの高さがあり、接地した状態のキャラを狙ったインクを完全に避けることができます。このとき AIM を下に調整すれば自分だけ相手を撃ち続けることができ、状況により無傷で敵を倒しきることすらできます。

裏や横から攻撃されたとき

反撃せず即座に逃げましょう。正面以外から撃たれた場合、勝つことは非常に困難です。必ず一旦逃げてから体制を立て直して反撃します。 追跡を防ぐにはボムを置いておくのがおすすめです。

ここで逃げきる確率を上げるために安全靴をはいておきましょう。

位置取り

位置取りは非常に大事です。大事なことは次の二点です。

  1. 相手の横から撃てる位置をとる
  2. 相手の復帰経路を塞ぐ。そのときは、塞ぐ経路を味方と被らないようにする。
  3. 相手の裏取りを防ぐためにマップをみる。

横から攻撃する

このゲームは接敵してから倒すまでの時間が比較的短いです。裏や横から敵を攻撃することが非常に重要です。 裏をとるのは時間がかかりすぎるし、更に裏をとられる危険性があるためむしろ上級者向けです。

横をとる戦術は壁を背にしやすいし、移動コストも低いので横をとる意識で戦闘に臨むのがいいです。

具体的には、敵の意識が味方に向いている間に横をとることが多いです。 味方のダイナモやシールド、スパショ、ボムラッシュ、ダイオウイカは非常に注意を引きやすいです。積極的に横からキルをとります。

具体的にどのようなケースで横がとれるのかは、さまざまな状況があると思います。あまり気構えず、正面から戦わず横から攻撃することを意識付けするだけで勝ちやすいと思います。

相手の復帰経路をふせぐ

ガチエリアなどでは相手の復帰を防ぐことが非常に大事です。

相手がエリアに復帰することができる経路は限られているので、前に陣取ってプレッシャーをかけるか、隠れてキルをとるなどして復帰を防ぎましょう。 味方と同じ経路をみていることがわかったら、違う経路をみるようにしましょう。

注意すべきことは裏取りです。このとき味方は復帰の妨害に注意が向いている場合が多く、一人に裏をとられるだけで全滅してしまうことも多々あります。

エリアなどで優位をとったときは裏取りを最大限警戒しましょう。

マップをみる

このゲームはマップをみることで敵の位置を知ることができます。

敵は自軍のインクを上を歩けませんので、必ずインクを上塗りしてから移動します。このとき色の塗り替わりが発生するので、マップを監視することで敵の移動をおおまかに知ることができます。

ずっと見ているのは難しいので、裏取りルートをたまに監視するくらいでも十分だと思います。 裏取りはマップをみて必ず防ぎましょう。

使うブキ

どのブキを使うかは非常に大事です。おすすめは .96ガロンデコです。

このブキは 2 発で敵を必殺できるうえ、射程が非常に長いです。また、サブのシールドは慣れていない敵相手には反則的に強さで、ほぼ初見殺しです。極め付けにはスペシャルのダイオウイカです。射程の長いブキを使うと接敵されたときに負けやすいですが、ダイオウを溜めておくだけで返り討ちにすることができます。(接敵した状態でダイオウイカを使うと、ラグの関係でほぼ必中です)

射程の長さ、シールド、ダイオウイカとデスしにくい要素が揃っているので、このブキを使うだけでキルデスがかなり改善されると思います。

単発が強いので積極的に攻めることもできるブキですが、どちらかといえば防御よりで、確実にキルをとっていくスタイルのほうが安定しやすいです。

シールドのつかいかた

キモはシールドです。シールドはうまく使えば前線維持、復帰支援、逃げ、攻めなど非常に多彩な戦術がとれます。

シールドにはさまざまな使い方がありますが、基本は接敵される前に置くこと、裏を取られたときはシールドを通り抜けること、通路の曲がり角は斜め設置をすることが重要です。

交戦地帯ではシールドを置くだけで敵が警戒してくれます。キルがとりにくくなりますが、味方の復帰時間を稼いだり、敵を後退させることで安全に前線維持をすることができます。

前線を維持することはスプラトゥーンにおいては重要です。なぜなら、エリア、ヤグラ、ホコすべてが前線を押し上げ、そのうえで敵の復帰を妨げて勝つゲームになっているからです。

キルをとるためのシールドもいいですが、前線を維持するための戦術的な設置を意識したほうが勝率も改善しやすいです。

ダイオウイカのつかいかた

ダイオウイカは非常に強力なスペシャルですが、強い状況は限られています。必ず使う状況は選びましょう。効果的なポイントは以下の通りです。

  1. 接敵されたとき、敵を返り討ちにするとき
  2. 複数敵の復帰阻止をするとき
  3. ヤグラなどで最後の押し込みをするとき
  4. 味方のシューターと一緒に攻め込むとき
接敵されたとき

勝てないことがわかったら即座に使いましょう。正直もったいないですが、デスするよりよっぽどましです。

せっかくのスペシャルを身を守るためだけに使ってしまうので、戦術的には効果が薄いです。

複数敵の復帰阻止をするとき

敵が 2,3 人で一気に復帰をしてきたときは、シールドで復帰経路を防ぐよりもダイオウイカで轢き殺したほうが強いです。

復帰を 2 人以上キルすることができれば、他の敵も数の差で倒しきることができます。すると合計で十数秒の間、敵を無防備にすることができ、この時間で試合が決まってしまうこともあります。

ヤグラなどで最後の押し込みをするとき

ダイオウイカを使うことで最後の数カウントを安全に押し切ることができます。自分が乗らなくても、ヤグラを狙っている敵を轢き殺したり、注意を引くだけでも十分強いです。

ホコでも同様です。

味方のシューターと一緒に攻め込むとき

ダイオウイカ単体では撃たれて押し返されるだけで、正直弱いです。ですが、味方にシューターがいれば一緒に攻め込むことでキルをとる&前線を押し上げることができます。

まとめ

.96 ガロンデコを使って物理で殴れば勝てる

JWT で CRSF 対策を実装する

Rails などのフレームワークCSRF 対策の実装を使わず、自前で CSRF 対策を行ってみる。

そもそも CSRF とは?

リクエストが「なぜ起こったか?」に関わらず、ブラウザが自動的に Cookie などのセッション情報を送信することを利用した攻撃方法。

例えば、ある人がサイト A にログインしているとする。この人がサイト B を訪問したとき、サイト B が iframe を経由してサイト A を埋め込んでいた場合、サイト A はログインされた状態で読み込まれる。 この性質を利用すれば、サイト B は、サイト A の GET リクエストでできるアクションを強制的に起こすことができる。

GET リクエストだけが危ないのかといえばそうではなく、iframe を target とした form を利用して POST リクエストも起こすことができる。

これを利用すれば、ログイン状態でデータ全削除機能の POST を叩かせる、といったことができてしまう。

対策方法

自サイトの form から自発的に送信されたリクエストであることを検証できれば、上記のような攻撃を防止することができる。

ではどうするか。よく使われるのはワンタイムトークンを form に input type=hidden などで埋め込んで一緒に送ってもらう方法。 しかし、ワンタイムトークンを使うとセッション情報を保持しなければならず、面倒臭い。 ここで、JWT を使うことでステートレスに CSRF 対策を行うことができる。

そもそも、自サイトを経由して送られたリクエストであることが検証できればよいのだから、ワンタイムトークンを使うまでもない。

具体的には subpost などとし、aud には最初のアクセス時に Cookie に保持させたランダム文字列を使い、サーバのもつ単一の秘密鍵で署名する。 この JWT を form の hidden に挿入しておき、そこから送信された POST リクエストを次のように検証する。

  1. JWT の検証が成功すること
  2. subpost であること。
  3. aud の値が、前述の Cookie に保持させた文字列(さっき aud に入れたやつ)と等しいこと。

JWT にはサーバのみにある秘密鍵を使った署名が付与されているので、勝手につくることや、改ざんはできない。もしそのようなトークンが送信された場合は検証に失敗する。勝手に値をいれて作ったり、改ざんしたりができないから、aud の値を自由に弄ることはできない。

このようにすると、aud がユーザ毎(ブラウザ毎)に違うからユーザ毎に違うトークンを使うことになり、トークン再利用攻撃も防止されている。

ソース

面倒臭いので割愛

まとめ

このようなセキュリティ関係は考え出すと面倒臭い。特にこの CSRF 脆弱性は単純な割にはかなり致命的な攻撃ができてしまう。 RubySInatra や Go の http/net などの軽量フレームワークを使う場合は、このような実装も考えていくことになる。

ほかによくある攻撃は SQL インジェクション、XSS など。 これらはデータベースドライバや言語レベルで対策が可能な場合が多く、今回の CSRF の実装が最も面倒臭い。

実際的には Rails などのフレームワークの恩恵を受けるのが楽。

Google の AMP に対応した HTML を書く

kaiinui.hatenablog.com

先日の記事では、AMP のさわりについて書きましたが、今回は具体的に AMP がどのようなフォーマットとなっているかを追うため実際に AMP HTML を書いてみます。

まず、AMP は HTML を拡張したフォーマットになっています。また、AMP HTML は単体で動き、それ自体が適正な HTML となっています。(ですから、ブラウザで AMP HTML を開いても普通に動きます。)

具体的には、次のようになっています。

<!doctype html>
<html ⚡>
<head>
  <meta charset="utf-8">
  <link rel="canonical" href="hello-world.html" >
  <meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no,minimal-ui">
  <style>body {opacity: 0}</style><noscript><style>body {opacity: 1}</style></noscript>
  <script async src="https://cdn.ampproject.org/v0.js"></script>
  <style type="text/css">
  body {
    padding: 0;
  }
  h1 {
    background: pink;
    color: white;
    margin: 0;
    padding: .5em;
  }
  </style>
</head>
<body>
<h1>AMPのテスト</h1>
<p>Hello World!</p>
<p><amp-img src="https://dl.dropboxusercontent.com/u/7817937/______film/Photo%202014-10-09%204%2049%2044.webp" width="200px" height="200px" /></p>
<p>このテキストは画像の下にあるよ</p>
</body>
</html>

この HTML は次の URL で試すことができます。

https://dl.dropboxusercontent.com/u/7817937/______film/amp.html

AMP HTML の書き方

さて、AMP HTML の書き方を解説してみます。

まずは、次の HTML から始めます。

<!doctype html>
<html ⚡>
<head>
  <meta charset="utf-8">
  <link rel="canonical" href="SOME_URL" >
  <meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no,minimal-ui">
  <style>body {opacity: 0}</style><noscript><style>body {opacity: 1}</style></noscript>
  <script async src="https://cdn.ampproject.org/v0.js"></script>
</head>
<body>
</body>
</html>

いくつかの不可解な部分がありますが「おまじない」だと思ってください。

テキストをおく

普通にテキストを置けばいいです。AMP HTML が通常の HTML であることがわかります。

<body>
<p>はろーわーるど</p>
</body>

画像を置く

画像は <amp-img> を使います。<img> ではないことに注意します。

<body>
<p><amp-img src="https://dl.dropboxusercontent.com/u/7817937/______film/Photo%202014-10-09%204%2049%2044.webp" width="200px" height="200px" /></p>
</body>

注意すべきことは次の 2 点です

  1. <p> で囲むこと。
  2. 必ず width, height を固定値で指定すること。

CSS を書く

AMP HTML は CSS なのでもちろん CSS も書けます。

<style type="text/css">
  body {
    padding: 0;
  }
  h1 {
    background: pink;
    color: white;
    margin: 0;
    padding: .5em;
  }
  </style>

...

<body>
<h1>タイトルバーっぽいやつ</h1>
<p>テキスト</p>
</body>

Google Analytics を置く

JavaScript は使えませんので、ガラケーのように 1x1 pixel の画像を使ってトラッキングを行います。 このとき、<amp-img> を使うと毎回リクエストを行うことが保証されないので、<amp-pixel> を使います。

Google Analytics のトラッキングピクセルは Measurement Protocol という仕様で規定されています。

<amp-pixel src="https://www.google-analytics.com/collect?v=1&tid=UA-XXXX-Y&cid=0000000&t=pageview&dp=%2Fpath_to_this_page" />

UA-XXXX-Y には GA ID を。dp には自身のページの相対 URL を指定します。

TwitterFacebook の Custom Audiences を使うときも、この <amp-pixel> を使います。

ほか、JavaScript 以外ならなんでもできます。

ということで、以上が主にできることになります。(他、動画や YouTube, Instagram, Twitter, iframe などが使えます。)

まあ普通の HTML だと思って差し支えありません。JavaScript が使えないことを除いて。

これらの構文を使って書いてみた AMP HTML が次の URL です。

https://dl.dropboxusercontent.com/u/7817937/______film/amp.html

テスト(開発)

#development=1 を AMP HTML の URL の末尾につけてアクセスすることで、開発モードにてページを表示することができます。

具体的には、次のような URL です。Chrome などの開発コンソールを開くと、AMP のデバッグログが表示されます。

https://dl.dropboxusercontent.com/u/7817937/______film/amp.html#development=1

ほかは?

github.com

参考

Google の高速ページ表示フォーマット AMP (Accelerated Mobile Page) をちょっと紐解く

www.suzukikenichi.com

GoogleTwitter が共同で AMP というフォーマットを制定しました。このフォーマットは、Facebook の Instant Articles のように高速なページ表示を実現するためのものです。

近年、広告や重度の JavaScript, 多すぎる/大きすぎる画像の増加が、ページを表示するために非常に長い時間がかかってしまう問題を引き起こしています。 この問題を解消するためのフォーマットが AMP (Accelerated Mobile Page) です。

実際どうなの?というところと、個人の感想を織り交ぜてちょっと紐解いてみます。

ほんとに速いの?

百聞は一見に如かず。実際に、スマホから下記のリンクにアクセスすることで AMP を試すことができます。

mars - Google Search

スマホからでないと動きません。

試してみると分かりますが、とんでもなくスムーズです。正直、ここまで変わるとは予想していませんでした。

(ところでどうでもいい個人の感想)

私個人としての驚きは、これが Web で実装されていることです。

高速ページ表示フォーマットといえば、FB Instant Articles のようにアプリを前提としているのが普通でした。なぜなら、高速化のために表現をそぎ落としたフォーマットをきちんと表示するためには、そのための専用のランタイムが必要だからです。従来は、アプリでネイティブにランタイムを積んで、ネイティブ UI で表示を行う、というのが当然な発想でした。

AMP が面白いのは HTML をベースにして仕様が定られており、ランタイムを AMP HTML から外部 JS でロードすることが規定されていることです(!) ですから、 AMP で書かれたページは通常どおりブラウザで読み込み、正常に表示することができます。 生粋の Web 屋であるところの Google らしい実装ですね。

どうやって速くしてるか

技術的なとこ。

AMP で特筆すべきは下記の 5 点です。

  1. AMP のランタイムは AMP Project の CDN から固定された URL で配信される
  2. AMP では JavaScript は一切使えない
  3. 画像や動画などは、大きさを固定で指定しなければならない
  4. CSS はインラインで記述することが勧められている(たぶん)
  5. 広告などは iframe 経由で表示される

これらについて書く前に、触れるべきことがあります。

モバイルにおいて速度を下げる天敵は、ずばり「リクエスト」です。「重さ(ファイルサイズ)」ではありません。

モバイルのネットワークは帯域幅こそ広くとられているのですが、リクエストに付随する遅延(レイテンシ)が大きいことが知られています。遅延とは、リクエストが実際に届くまでにかかる時間のことです。リクエストが実際に届いてからダウンロードが開始しますから、いかにダウンロードが速くとも、遅延が大きいと全体で見たダウンロード時間が長くなります。

先ほどの事実を言い換えると、モバイルのネットワークは、リクエストが届いてからのダウンロードこそ速いが、リクエストが届くまでが長いという性質があります。

以上より、全体でみたファイルのサイズを下げるよりも、リクエスト数を少なくする方が効果が上がりやすい、ということがわかります。

この点を踏まえ、さきほど挙げた 5 点の施策を振り返ります。

AMP のランタイムは AMP Project の CDN から固定された URL で配信される

  • どうしても AMP HTML に付随してしまうランタイムが重ければ意味がありません。AMP のランタイムはそこそこ大きく、gzip 後で 38 KB です。(jQuery と同じくらい)
  • しかし、ランタイムを単一の URL から配信することで、一度でも AMP HTML を開けばクライアント側でキャッシュされるよう設計がなされています。

AMP では JavaScript は一切使えない

  • 少し専門的ですが、JavaScriptレンダリングがブロックされないよう配慮されています。重くなりがちな JavaScript のリクエストも不要になります。
  • いまの Web でもっとも多くリクエストを発行しているのは広告、ソーシャル、計測の JavaScript です。これらを強制的に切ることは、多大なリクエスト数削減をもたらします。
  • AMP HTML はホスト側(AMP HTML を表示するアプリ / サービス)でキャッシュすることが規定されています。JavaScript を切ることで、セキュリティを担保しています。

画像や動画などは、大きさを固定で指定しなければならない

  • 大きさが固定されていることで、画像を取得し終わらなくても、その分の高さを空けておくことができます。画像がどんどん入って文字がどんどん下にいく…といった表示のがくつきを防止できます。(リフローといって、処理が重いです。)

CSS はインラインで記述することが勧められている(たぶん)

  • 少し専門的ですが、CSSレンダリングをブロックします。インラインで書くことで、HTML と一緒のリクエストで同時に配信でき、表示までが早くなります。
  • サンプルプロジェクトがすべてインラインで書かれていたのですが、別に外部 CSS を使ってもいいのかもしれません。

広告などは iframe 経由で表示される

  • 広告はリクエストも多いし、画像 / 動画のファイルサイズも大きいことが多いです。ですから、広告の表示は通常ページのスピードに大きな影響を与えます。
  • AMP は iframe の表示の優先度を意図的に下げています(たぶん)ですから、広告はどこにあろうとコンテンツが先に表示されてから、あとになって表示されることになります。
  • ちなみにページ全体が iframe で表示されたりしないように、iframe は違うドメインのものを指定しなければならないようになっています

つまり?

HTML を 1 つリクエストするだけで表示がほとんど完了するように工夫されています。ほとんど、と書いたのは画像や動画, 広告などをロードしなければ完了しないからです。しかしながら、これらのリソースが読み終わらなくても、高さはあらかじめ記述されているので、ページ全体はすぐに要素の配置が終えられるようになっています。

リクエスト数の圧倒的な削減、要素の再配置がないことにより事前レンダリング(裏側で事前に表示を始めておくこと)の負荷が極めて小さくなっています。この利点が、先に示した Google の AMP 実装のようなスムーズなページ遷移を実現しています。

ところで、アナリティクスは…できます!

心配になりますよね… Google Analytics ははたして動くのか…??

JavaScript は全く動きませんが、<amp-pixel> という仕様があります。 これは、指定した src に毎回リクエストを行うタグです。 この src に解析用のピクセル(1px の画像)を指定すればよい、というわけです。

Google Analytics の場合は Measurement Protocol がというピクセルの実装がありますので、こちらを利用すればよいです。

原理はメルマガやガラケーのアナリティクスと同じです。

ascii.jp

AMP があることをどうやって Google に教えるか?

おそらく次の様な仕様になりそうです。(まだ確定してない)

<link rel="amphtml" href="hoge.amp.html" />

まとめ?

  • AMP ページはめっちゃ速いしサクサク。まるでネイティブ。
  • AMP を実装すると、Google から URL 遷移せずにページが表示されます。ぶっちゃけそれはどうなの…
  • Twitter も実装するらしい(策定に関わってます)
  • Facebook は対応するのかな?知りません
  • AMP のプレビューを見る限り、SEO アドバンテージあるみたいです…最近の Google は自社の仕様を広めるためのバラマキに余念がないですね…

参考 URL

iOS, Android 対応のディープリンクサービス HOKO

HOKO いいですね。Product Hunt でもいい感じだったらしいです。

hokolinks.com

できることは

  1. デバイス毎の遷移先振り分け(iOS, Android, PC)
  2. アプリインストール済みかどうかで振り分け
    • アプリで開く(URL Scheme
    • アプリストアで開く(インストール後のディープリンク紐付けあり)
    • なにかしらの URL にフォールバック

iOS ではアプリインストール済みであればアプリで。なければ Web をみせる。Android では常に Web」みたいなフォールバックが簡単にできます。 インストール訴求を強くした場合は、「iOS ではアプリインストール済みであればアプリで。なければ App Store を表示し、インストール後にそのリンクに紐付いた内容に飛ぶ。Android では常に Web」みたいなことができます。

App Store を挟んでいるのにもかかわらず、インストール後リンクに紐付いた場所に自動で飛ぶ、ということができるのは「インストール後のディープリンク紐付け」のおかげです。

「インストール後のディープリンク紐付け」というのは、文字通り HOKO リンクに含まれるディープリンク情報を、アプリインストール後までまたがって保持してくれる機能です。 この機能のおかげで、アプリをインストールしたあとすぐにそのリンクのコンテンツを表示することが可能です。

つまりとりあえず HOKO リンクにしとけばフォールバックいろいろしやすいし楽だということです。

あとはリンクをつくる API があります。

料金はいまは無料っぽいです。料金あんまり言及されてない。

同様の内容を提供しているサービスとしては Yozio があります。こっちはそこそこ高い。