JavaScriptを使えば閲覧者のページ滞在時間を計測することができる。これはサーバーサイドのPHPなどにはできない芸当で、クライアントサイドのプログラムだからこそできる芸当だ。この記事ではJavaScriptのsetintervalとperformance.nowでページ滞在時間を取得する方法を説明する。
その前に、なぜページ滞在時間を取得したいのかについてはっきりさせておこう。ウェブマスターやらマーケターやらウェブ運用をしている人はまず間違いなくgoogle analyticsというアクセス解析ツールを使っていると思う。このgoogle analyticsには直帰率という指標があるのだが、多くのウェブ運用者にとってこの直帰率はとても気になる指標なのである。
直帰率が高いと1ページだけ閲覧してサイトを閉じたり、あるいは別のウェブサイトに移動したことを意味するから、たいていのウェブ運用者はこの直帰率を下げようと日々苦労と工夫を重ねている。しかし、直帰率を下げたいという前提はそもそも正しいのだろうか?
いまここに直帰率が高いページが2つあるとしよう。
- 1つのページは100人の人がそのページを見て、そのうち9割の人が熱心にページを閲覧しページを閉じ、残り1割は軽くみてページを閉じた
- もう一方のページも100人が閲覧したが、9割の人は軽くながめてページを閉じ、残り1割の人が熱心に閲覧しページを閉じた
1ページしか閲覧していないのだからどちらも直帰率が高いという点では同じだが、ページの価値は上のほうが高いのは明らかだろう。単に直帰率を見るだけではページの正しい分析ができない。この問題を解決するためにJavaScriptで閲覧時間を取得しようというのが今回の趣旨である。
ポイントはスクロール率
JavaScriptでページ滞在時間を取得するにはいくつかの機能を使う。1つはperformance.nowで、これはタイマーとして使用する。もう一つはsetIntervalで、これはサーバーにデータを送信するために使う。もう1つはwindow.innerHeightだ。これはスクロール率を取得するのに使う。このスクロール率が重要な点である。
タイマー開始
まずはページ上部にタイマー開始の一文を書く。constで定数にした理由はページの読み込み開始時間が変わることはないから。headタグのなるべく上のほうに記述するといいだろう。
const start = performance.now();
</script>
次にデータ送信先のプログラムを指定しておく。これは setIntervalより上なら書く場所はどこでもいい。
タイマーを終わらせる方法
ページの下部にタイマーを終わらせる記述を書くのだが、問題はどうやってタイマーを終わらせるか?だ。httpの仕様上、一度レスポンスしたページに対してサーバーサイドで働きかけることはできないのは当然だし、JavaScriptでも少し工夫しないといけない。そこで考えたのがスクロール率だ。JavaScriptにはウィンドウ画面の高さと、その中におけるマウスの座標を取得する機能がある。これを組み合わせることでスクロール率が取得できる。
なぜスクロール率かというと、閲覧者がページに関心があるならば、ページ下部まで間違いなく遷移して読むからだ。滞在時間が長くてもページ上部に留まったままなら、閲覧者はページを表示させてトイレに行っただけかもしれない。良質なデータを得るには、こういう可能性は少しでもいいので潰しておく必要がある。
スクロール率をたとえば25%、50%、75%、100%に分割して、それぞれのスクロール率に達した時点での時間をperformance.now();で取得してendという変数に入れる。これは定数でないことに注意しよう。
scroll_position = vh + window.pageYOffset;
let end;
if(scroll_position / page_height < 0.25){
end = performance.now();
} else if(scroll_position / page_height >= 0.25 && scroll_position / page_height <= 0.5 ){
end = performance.now();
} else if(scroll_position / page_height >= 0.5 && scroll_position / page_height <= 0.75 ){
end = performance.now();
} else if(scroll_position / page_height >= 0.75 && scroll_position / page_height < 0.90){
end = performance.now();
} else if(scroll_position / page_height >= 0.9){
end = performance.now();
}
const staying_time = end – starttime;
const senddata = new FormData();
navigator.sendBeacon(send_data, senddata);
};
setInterval(function(){scrolllog(view_height,start)},30000);
上記コードをページ最下部から読み込む。sendBeaconでデータを送信し、そのプロセスをseIntervalで定期的に回す。上記例では30秒にしたが、データ取得をどこまで貪欲に、あるいは緩くするかはウェブの運用状況による。アクセス数が多いウェブサイトで取得タイミングを5秒ごとに設定したら、かなりの負荷がかかるだろう。
ここで大事な点は、完璧なデータ取得は放棄するということ。この諦めが大事だ。完璧を求めるとデータ取得は永遠にできないだろう。なお、データ取得に関しては様々なアプローチがあり、ここで書いたのはあくまで一例だ。達人プログラマーならもっときれいにデータ取得できるだろうから、本記事の内容はあくまで参考程度にとどめてほしい。
なお、この記事ではjs送信されたデータを受けた側の処理については書いていないが、くれずれもセキュリティ対策を忘れずに。