HTML の a タグの ping 属性でお手軽に AB テストしてみよう!
2023-03-15-1
[Programming]
ping属性を使ってお手軽にABテストをやってみる、という話。
今あるウェブページを最小限いじるだけで、簡単にABテストできる。
まずは ping 属性について。
a 要素(a タグ)に ping 属性を設定しておくと、リンクをクリックしたときに同時に ping を送ることができる。
ここで言う「ping を送る」というのは、ブラウザが裏で ping で指定された URL にアクセスすること。
上のコードだと、クリックすると yahoo のページへ飛ぶと同時に、ブラウザは裏で https://log.example.com/log/0123 に POST でアクセスする。
例えばこんなログがウェブサーバ (log.example.com) のアクセスログに残る。
これを数えれば a タグでサイト外に飛んで行った回数が追える。
ping の URL には POST でアクセスされるため「ping="https://log.example.com/log.cgi?id=123"」だとパラメータは無視される。
ping のアクセス先 URL に該当する場所に 0 サイズファイル作っておいたり、RewriteRure でどこかに飛ばしたりしておく。
または、集計時は error_log を見ることにしておく。
テストしたい要素に2つのバリエーションがあって、確率1/2で切り替えてそれぞれのクリック数を集計したい。
それでどっちが良さそうかを判定したい。
例1: a 要素のテキストについて、「今すぐ読む」と「ブラウザで今すぐ読む」のどっちの文言の方がクリックされやすいか?
script 部分は 1/2 の確率でターゲットのテキストと ping URL を A のものと B のものに振り分けているだけ。
しばらくしてから、ping URL のサーバのアクセスログで "/abtest/id/sample-t1__A" と "/abtest/id/sample-t1__B" の数を数えてどちらが多いか見るだけ。
(率を出したい場合は元のページのアクセス数で割る)
例2: a 要素のスタイルについて、2つの候補のどっちがクリックされやすいか?
比較したい2つの候補 (id="t2__A" と id="t2__B") を両方書いてしまう方式。
2つの候補はどちらも "display: none" で非表示にしておく。
script 部分で 1/2 の確率で A、B どちらかを表示 ("display: block") にする。
ちょっと面倒だし、コードもごちゃごちゃしちゃう。
「お手軽にABテスト」から逸脱してる感じがする。
私が運営してる Kindle セール情報サイト「キンセリ」で、「リンクテキストの候補2つのうちどっちがよくクリックされる?」実験をやってみました。
キンセリのセール特設ページでは、「期間限定無料のマンガ作品」または「読み放題対象ではない0円のマンガ作品」にのみ、「ブラウザで直接マンガが読めるむビューワ」へのリンクが付きます。
そのリンクの文言を変えてどちらがクリックされやすいか調べました。
集計期間は2023年1月1日から1月31日まで。
最初の1週間弱は A が優勢なのですが、最終的には A:1245, B:1397 で B が優勢となりました(カイ2乗検定で有意)。
なぜ、最初は A が優勢だったのか?
実は調査前の元々の文言は B でして、A が出ると今まで違って目新しく感じてクリックしちゃうケースが増えたのかも。
ある程度、長期間やらないとダメなのですね。
なにはともあれ B が優勢だったので、その後の文言は「ブラウザで今すぐ読む」で固定しました。
こんな感じで、キンセリではカジュアルにABテストして日々の改善を行っています。
みなさんも自分のサイトとかブログとかで手軽にABテストしてみては!?
今あるウェブページを最小限いじるだけで、簡単にABテストできる。
ping 属性について
まずは ping 属性について。
a 要素(a タグ)に ping 属性を設定しておくと、リンクをクリックしたときに同時に ping を送ることができる。
ここで言う「ping を送る」というのは、ブラウザが裏で ping で指定された URL にアクセスすること。
<a href="https://www.yahoo.co.jp/" ping="https://log.example.com/log/0123">クリックして!</a>
上のコードだと、クリックすると yahoo のページへ飛ぶと同時に、ブラウザは裏で https://log.example.com/log/0123 に POST でアクセスする。
例えばこんなログがウェブサーバ (log.example.com) のアクセスログに残る。
X.X.X.X - - [01/Feb/2023:21:53:45 +0900] "POST /log/0123 HTTP/1.1" 301 269 "-" "Mozilla/5.0 ..."
これを数えれば a タグでサイト外に飛んで行った回数が追える。
ping の URL には POST でアクセスされるため「ping="https://log.example.com/log.cgi?id=123"」だとパラメータは無視される。
ping のアクセス先 URL に該当する場所に 0 サイズファイル作っておいたり、RewriteRure でどこかに飛ばしたりしておく。
または、集計時は error_log を見ることにしておく。
ABテストのための簡単な仕掛け
テストしたい要素に2つのバリエーションがあって、確率1/2で切り替えてそれぞれのクリック数を集計したい。
それでどっちが良さそうかを判定したい。
例1: a 要素のテキストについて、「今すぐ読む」と「ブラウザで今すぐ読む」のどっちの文言の方がクリックされやすいか?
<h1>SAMPLE: テキストの入れ替え</h1> <div> <a href="https://yahoo.co.jp/" id="t1" ping="https://example.com/abtest/id/sample-t1"> 今すぐ読む </a> </div> <script> document.addEventListener('DOMContentLoaded', function() { const e = document.getElementById('t1'); if (Math.random() < 0.5) { e.innerText = "今すぐ読む"; e.setAttribute('ping', e.getAttribute('ping') + '__A'); } else { e.innerText = "ブラウザで今すぐ読む"; e.setAttribute('ping', e.getAttribute('ping') + '__B'); } }); </script>
- ターゲットの a 要素に ping 属性 (URLのプレフィックス) を書く
- script で操作するために id 属性を足す
- "<script>...</script>" を足す
script 部分は 1/2 の確率でターゲットのテキストと ping URL を A のものと B のものに振り分けているだけ。
しばらくしてから、ping URL のサーバのアクセスログで "/abtest/id/sample-t1__A" と "/abtest/id/sample-t1__B" の数を数えてどちらが多いか見るだけ。
(率を出したい場合は元のページのアクセス数で割る)
例2: a 要素のスタイルについて、2つの候補のどっちがクリックされやすいか?
<h1>SAMPLE: 表示/非表示の切り替え</h1> <div id="t2__A" style="display: none"> <a href="https://yahoo.co.jp/" ping="https://yapi.ta2o.net/abtest/id/sample-t2__A"> <span style="background-color: red; color: white; padding: 1rem;">今すぐ読む</span> </a> </div> <div id="t2__B" style="display: none;"> <a href="https://yahoo.co.jp/" ping="https://yapi.ta2o.net/abtest/id/sample-t2__B"> <span style="background-color: pink; padding: 1rem;">今すぐ読む</span> </a> </div> <script> document.addEventListener('DOMContentLoaded', function() { if (Math.random() < 0.5) document.getElementById('t2__A').style.display = 'block' else document.getElementById('t2__B').style.display = 'block' }); </script>
比較したい2つの候補 (id="t2__A" と id="t2__B") を両方書いてしまう方式。
2つの候補はどちらも "display: none" で非表示にしておく。
script 部分で 1/2 の確率で A、B どちらかを表示 ("display: block") にする。
ちょっと面倒だし、コードもごちゃごちゃしちゃう。
「お手軽にABテスト」から逸脱してる感じがする。
実際にお手軽ABテストをやってみた結果
私が運営してる Kindle セール情報サイト「キンセリ」で、「リンクテキストの候補2つのうちどっちがよくクリックされる?」実験をやってみました。
キンセリのセール特設ページでは、「期間限定無料のマンガ作品」または「読み放題対象ではない0円のマンガ作品」にのみ、「ブラウザで直接マンガが読めるむビューワ」へのリンクが付きます。
そのリンクの文言を変えてどちらがクリックされやすいか調べました。
- A. "今すぐ読む"
- B. "ブラウザで今すぐ読む"
集計期間は2023年1月1日から1月31日まで。
最初の1週間弱は A が優勢なのですが、最終的には A:1245, B:1397 で B が優勢となりました(カイ2乗検定で有意)。
なぜ、最初は A が優勢だったのか?
実は調査前の元々の文言は B でして、A が出ると今まで違って目新しく感じてクリックしちゃうケースが増えたのかも。
ある程度、長期間やらないとダメなのですね。
なにはともあれ B が優勢だったので、その後の文言は「ブラウザで今すぐ読む」で固定しました。
こんな感じで、キンセリではカジュアルにABテストして日々の改善を行っています。
みなさんも自分のサイトとかブログとかで手軽にABテストしてみては!?