Django でも
この<link rel="prefetch">
を
以下説明を
作った 動機
作成の
- 通常の
ページでは、 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. を使用しているのであれば、 以下のような 記述で スケジュール実行が できます。 勿論、CRONJOBS = [ ('30 01 * * *', 'django.core.management.call_command', ['store_ga'], {}, '>> /var/log/store_ga.log'), ]
crontab に 定義して スケジュール実行も 可能です。 テンプレートタグを
追加する
テンプレートのhead タグ内に 以下の 記述を 追加します。
これで、Google Analytics の データ解析結果を 元に <link rel="prefetch">
が追加されます。 {% load guess %} {% ifinstalled guess %} {% prefetch request.path %} {% endifinstalled %}
Django REST Framework (DRF) support
Django template 以外の
すべての
ビューを 含める
urls.py に以下の 記述を 追加してください。 上記のfrom django.conf.urls import url, include urlpatterns += [ url('apis/', include('guess.urls')), ]
設定で、 URL <your_domain >/apis/guessresult/<pagepath >/<effectivetype >
でAPIへ アクセスできます。 クライアント側の
実装
以下のJavaScript関数を クライアント側に 実装します。
Web API を呼び出し、 その 戻り値を 元に、 次に 遷移する 確率が 高い ページを、 prefetchタグを 使って 先読みします。
'/apis/guessresult/'
の部分は urls.py
の記述に 合わせて 調整する 必要が あります。 上記、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); }
guessNextPages() を '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 で
似たような ライブラリが あると、 仕事にも 適用できる。
以上です。
コメント