Django でも Guess.js は使えますが、クライアント側での仕込みになり SSR を行うページで使用することは基本的にできません。
このため、動的に<link rel="prefetch">
を追加する kemsakurai/django-guess: django-guess というライブラリを作成してみました。
以下説明を記載します。
作った動機
作成の動機は以下になります。
- 通常のページでは、Guess.js を使って Google Analytics のアクセスの結果に基づいた ページの先読みが可能。
- AMP ページでも ServiceWorker からの先読みはできそう。
- ServiceWorker を使わなくても、
<link rel="prefetch">
を AMP のページごとに追加できれば良い。 - Guess.js のやりたいことは、Python でもできそう。
- Django の Command と Template タグを作る。
getting started
-
インストール
pip install git+https://github.com/kemsakurai/django-guess
-
settings.py の INSTALLED_APPS の編集
INSTALLED_APPS に以下の設定を追加してください。
INSTALLED_APPS = ( .... "guess", ... )
-
Google Analytics の VIEWID と、credentials.json の配置先を追加
settings.py に VIEWID と、Service Accounts | Google Earth Engine API | Google Developers の credentials.json の 配置先を追加してください。
PREFETCH_CONFIG
は回線ごとの遷移確率の閾値になり、COMMAND_CONFIG
の値は、Django Command 内で使用する閾値になります。
GUESS_SETTINGS = {
"VIEW_ID" : "103185238",
"CREDENTIALS" : "/home/user_name/credentials.json",
"PREFETCH_CONFIG": {'4g': 15, '3g': 30, '2g': 45, 'slow-2g': 60},
"COMMAND_CONFIG" : {'RATIO_TO_EVALUATE': 0.20, 'LOWER_LIMIT_TRANSITION_PROBABILITY': 0.05}
}
-
マイグレーションの実行
migrate を実行すると、guess_guessresult
テーブルが作成されます。
これは、Google Analytics のデータ解析結果を格納するテーブルになります。
python3.6 manage.py migrate
-
コマンドを実行
store_ga
を実行すると、Google Analytics のデータ解析結果を登録します。
python3.6 manage.py store_ga
-
スケジュール実行
kraiz/django-crontab: dead simple crontab powered job scheduling for django. を使用しているのであれば、以下のような記述で スケジュール実行ができます。
勿論、crontab に定義してスケジュール実行も可能です。CRONJOBS = [ ('30 01 * * *', 'django.core.management.call_command', ['store_ga'], {}, '>> /var/log/store_ga.log'), ]
-
テンプレートタグを追加する
テンプレートの head タグ内に以下の記述を追加します。
これで、Google Analytics のデータ解析結果を元に<link rel="prefetch">
が追加されます。
{% load guess %} {% ifinstalled guess %} {% prefetch request.path %} {% endifinstalled %}
Django REST Framework (DRF) support
Django template 以外の Frontend からも使用できるように Web API を提供しています。
-
すべてのビューを含める
urls.py に以下の記述を追加してください。
上記の設定で、URLfrom django.conf.urls import url, include urlpatterns += [ url('apis/', include('guess.urls')), ]
<your_domain>/apis/guessresult/<pagepath>/<effectivetype>
で APIへアクセスできます。 -
クライアント側の実装
以下のJavaScript関数をクライアント側に実装します。
Web API を呼び出し、その戻り値を元に、次に遷移する確率が高いページを、prefetchタグを使って先読みします。
'/apis/guessresult/'
の部分はurls.py
の記述に合わせて調整する必要があります。
上記、guessNextPages() をfunction prefetch(url) { console.log(url); let hint = document.createElement('link'); hint.rel = 'prefetch'; hint.href = url; hint.as = 'html'; hint.crossorigin = 'use-credentials'; document.head.appendChild(hint); } function getConnection() { if (!window || !window.navigator || !window.navigator.connection) { return '3g'; } return window.navigator.connection.effectiveType || '3g'; } function guessNextPages() { var xhr = new XMLHttpRequest(); // ハンドラの登録. xhr.onreadystatechange = function() { switch ( xhr.readyState ) { case 4: // データ受信完了. if( xhr.status == 200 ) { var data = xhr.responseText; var jsonData = JSON.parse(data); for (var i = 0; i < jsonData.length; i++) { prefetch(location.origin + jsonData[i]['page_path']); } } else { console.log("Response error! status=" + xhr.status); } break; } }; var urlParam = encodeURIComponent(location.pathname); xhr.open( 'GET', '/apis/guessresult/' + urlParam + '/' + getConnection() + '/' + '?format=json', true ); // POST 送信の場合は Content-Type は固定. xhr.setRequestHeader( 'Content-Type', 'application/json' ); xhr.send(null); }
'DOMContentLoaded'
等のタイミングで呼び出せば、先読みが行われます。
window.addEventListener('DOMContentLoaded', function() { guessNextPages(); })
-
HTTPサーバーの設定変更
Web API のパラメータ<pagepath>
にはスラッシュ(/) が含まれます。
Apache 2.4 の場合は、AllowEncodedSlashes
を Virtual Host 設定内に追加します。
AllowEncodedSlashes On
先読みを行うページの決定方法
Guess.js の実装に忠実なわけではありませんが、以下のようなロジックで先読み対象のページを決定します。
-
コマンドの実行した日から 180 日分の Google Analytics のデータを取得。 データ取得時以下のディメンション、メトリクスを指定。
- ディメンション
- ga:pagePath
- ga:previousPagePath
- メトリクス
- ga:pageviews
- ga:exits
- ディメンション
-
previousPagePath が
(entrance)
のデータを除外し、previousPagePath ごとの pagePath の 合計ページビューを計算。 - ページビュー多いページ 上位 20 % を抽出。 [1]:当サイトのアクセス数を解析した結果、パレートの法則に従っていそうだったので、上位 20 % としています。
3.
の抽出結果から、10% 以上の確率で遷移が発生したページのみを抽出。4.
の抽出結果を テーブルに登録する。
TODO
解析データの取得期間、閾値をコントロールできるようにする。- 別の計算方式で先読み対象のページを特定できるようにする。
感想
以下、実装した感想を記載します。
- Google Analytics のデータの単純集計なので、実装はそこまで大変ではなかった。
- Pandas で実装したが、Pandas を使用せずとも組める。パフォーマンス的には使わない方が速度は出そうに思った。
- Java で 似たようなライブラリがあると、仕事にも適用できる。
以上です。
コメント