Google Analyatics 3 には、サイトの速度というデータが記録されています。
このデータはReal User Monitoring に分類されるデータで、デフォルトでは1%のユーザーの速度が記録されています。
どのサイト、サービスでも大概Google Analytics は導入されているので、
いざ、「フロントエンドの速度も含めたパフォーマンスの悪いページを特定したい」といったケースで活用できそうに思います。
この記事ではそのようなケースを想定して、速度レポートとしてどのようなデータが取得できるのか試してみました。

前提

OS、PythonのVersion必要なライブラリの情報を記載します。

  • OS
!sw_vers
ProductName:    macOS
ProductVersion: 11.6
BuildVersion:   20G165
  • Python の Version
!python3 -V
Python 3.7.2

必要なライブラリのインストール

!pip3 install --upgrade pip
!pip3 install pandas
!pip3 install google2pandas
!pip3 install oauth2client
!pip3 install matplotlib

データの戻り形式を確認してみる。

このブログのサイトの速度を取得します。
Google Anlayticds V4 のAPIの実行時のキーの指定方法は、Dimensions & Metrics Explorer を確認しながら指定しました。

ページ読み込み時間を取得して、ヒストグラム表示する

ページ読み込み時間を取得してヒストグラム表示します。
GAのAPIの値はga:pageLoadTimega:pageLoadSamplega:avgPageLoadTimeを指定しています。
戻り値をみる限り上記は、以下の関係が成り立ちます。

ga:pageLoadTime / ga:pageLoadSample = ga:avgPageLoadTime

ヒストグラムに表示する値は、ga:avgPageLoadTimeを使用します。
Google AnalyticsとNavigation Timing API - Qiita が参考になりますが、ページ読み込み時間は、Navigation Timing API を使用して以下の計算式で求められる値です。
performance.timing.loadEventStart - performance.timing.navigationStart。      

from google2pandas import *
view_id = '103185238'
query = {
    'reportRequests': [{
        'viewId' : view_id,
        'dateRanges': [{
            'startDate' : '30daysAgo',
            'endDate'   : 'today'}],
        'dimensions' : [
            {'name' : 'ga:pagePath'}      
        ],
        'metrics'   : [
            {'expression' : 'ga:pageLoadTime'},
            {'expression' : 'ga:pageLoadSample'},
            {'expression' : 'ga:avgPageLoadTime'},            
        ],
    }]
}
conn = GoogleAnalyticsQueryV4(secrets='./ga_client.json')
df = conn.execute_query(query)
df['avgPageLoadTime'].astype(float).hist(bins=50)
<AxesSubplot:>

Image from Gyazo

ページ読み込み時間を取得して、パフォーマンスが悪い上位10%のページを取得する

from google2pandas import *
view_id = '103185238'
query = {
    'reportRequests': [{
        'viewId' : view_id,
        'dateRanges': [{
            'startDate' : '30daysAgo',
            'endDate'   : 'today'}],
        'dimensions' : [
            {'name' : 'ga:pagePath'}      
        ],
        'metrics'   : [
            {'expression' : 'ga:pageLoadTime'},
            {'expression' : 'ga:pageLoadSample'},
            {'expression' : 'ga:avgPageLoadTime'},        
        ],
    }]
}
conn = GoogleAnalyticsQueryV4(secrets='./ga_client.json')
df = conn.execute_query(query)
df['avgPageLoadTime'] = df['avgPageLoadTime'].astype(float)
df = df.sort_values(by='avgPageLoadTime', ascending=False)
df[df['avgPageLoadTime']>=df['avgPageLoadTime'].quantile(0.9)]
.dataframe tbody tr th:only-of-type { vertical-align: middle; } .dataframe tbody tr th { vertical-align: top; } .dataframe thead th { text-align: right; }
pagePath pageLoadTime pageLoadSample avgPageLoadTime
23 /blog/django-model-を作成したがmakemigrations-で-no-c... 17126 1 17.126000
17 /blog/Customize-Google-Form-and-set-hidden-field/ 32875 3 10.958333
3 /amp/blog/Python-implements-statistical-test-m... 8010 1 8.010000
36 /blog/jar-ファイル作成時にminify-maven-plugin-を使ってcssj... 6586 1 6.586000
9 /blog/About-JavaScript-keyboard-shortcut-library/ 11806 2 5.903000
43 /blog/pip-インストールする-ライブラリの-version-番号を調べる/ 11417 2 5.708500
15 /blog/Calculate-Weibull-distribution-in-Python/ 22432 4 5.608000

pandas のquantileと条件式を組み合わせると上位10%の遅いページが抽出できました。

サンプリング数が少なすぎると、異常値が上位に来ている可能性があるため、サンプリング数でフィルターをかけるか、 異常値の除去も実施したほうが良いかもしれません。

サーバーの応答速度を取得してヒストグラムを表示する

サーバーの応答速度を取得してヒストグラムを表示します。
ga:serverResponseTimega:avgServerResponseTimega:speedMetricsSample を取得し、ヒストグラム表示には、ga:avgServerResponseTime を使用します。

from google2pandas import *
view_id = '103185238'
query = {
    'reportRequests': [{
        'viewId' : view_id,
        'dateRanges': [{
            'startDate' : '30daysAgo',
            'endDate'   : 'today'}],
        'dimensions' : [
            {'name' : 'ga:pagePath'}      
        ],
        'metrics'   : [
            {'expression' : 'ga:serverResponseTime'},
            {'expression' : 'ga:speedMetricsSample'},
            {'expression' : 'ga:avgServerResponseTime'},        
        ],
    }]
}
conn = GoogleAnalyticsQueryV4(secrets='./ga_client.json')
df = conn.execute_query(query)
df['avgServerResponseTime'].astype(float).hist(bins=50)
<AxesSubplot:>

Image from Gyazo

サーバーの応答時間を取得して、パフォーマンスが悪い上位10%のページを取得する

from google2pandas import *
view_id = '103185238'
query = {
    'reportRequests': [{
        'viewId' : view_id,
        'dateRanges': [{
            'startDate' : '30daysAgo',
            'endDate'   : 'today'}],
        'dimensions' : [
            {'name' : 'ga:pagePath'}      
        ],
        'metrics'   : [
            {'expression' : 'ga:serverResponseTime'},
            {'expression' : 'ga:speedMetricsSample'},
            {'expression' : 'ga:avgServerResponseTime'},        
        ],
    }]
}
conn = GoogleAnalyticsQueryV4(secrets='./ga_client.json')
df = conn.execute_query(query)
df['avgServerResponseTime'] = df['avgServerResponseTime'].astype(float)
df = df.sort_values(by='avgServerResponseTime', ascending=False)
df[df['avgServerResponseTime']>=df['avgServerResponseTime'].quantile(0.9)]
.dataframe tbody tr th:only-of-type { vertical-align: middle; } .dataframe tbody tr th { vertical-align: top; } .dataframe thead th { text-align: right; }
pagePath serverResponseTime speedMetricsSample avgServerResponseTime
7 /blog/About-checklists-used-in-system-developm... 819 1 0.819
2 /amp/blog/java-url文字列からクエリストリングを取得/ 816 1 0.816
39 /blog/lighthouse-pwa-警告-の対処-する/ 726 1 0.726
58 /blog/spring-boot-でapplication-起動時にorgspringfr... 700 1 0.700
4 /amp/blog/pythonで相関係数の計算をする/ 680 1 0.680
38 /blog/jpa-query-selecting-only-specific-columns/ 625 1 0.625
42 /blog/monitorevents-で-input-タグの発生イベントを監視する/ 1695 3 0.565

データを見る限り言えそうなこと

データをみる限り以下のことが言えそうです。

  • ページ読み込み速度と、サーバーの応答速度だと、速度分布の傾向が異なる。
  • サーバーの応答速度が遅いページがそのまま、読み込み速度が遅いページになる訳ではない。

参考

以下のページが参考になりました。

以上です。


コメント