超速! Webページ速度改善ガイド ── 使いやすさは「速さ」から始まる (WEB+DB PRESS plus) | 佐藤 歩, 泉水 翔吾 |本 | 通販 | Amazon読んでいたところ、Server-Timing - HTTP | MDNいうものがあることを知りました。

Django で middleware を作ると、いい感じに Response Time を記録できそうでしたので、試しに設定してみました。
結果を記載します。


前提

以下の環境で動作確認しています。

  • OS

    cat /etc/centos-release
    CentOS Linux release 7.6.1810 (Core)     
    

  • Django version

    pip list | grep Django
    Django                      1.10.8   
    


作成した middleware の説明

Show page generation time in Django - Stavros’ Stuff参考に、StatsMiddleware作成しました。

  • middleware.py

    import time
    
    class StatsMiddleware(object):
        def process_request(self, request):
            "Store the start time when the request comes in."
            request.start_time = time.time()
    
        def process_response(self, request, response):
            "Calculate and output the page generation duration"
            # Get the start time from the request and calculate how long
            # the response took.
            duration = time.time() - request.start_time
    
            # Add the header.                                                                                                                                                                
            response["Server-Timing"] = 'res;desc="Server app response time";dur=' + str(int(duration * 1000))
            return response
    

  • Headerの設定値の説明
    以下の形式で、設定されます。
    res;desc="Server app response time";dur=20

    • res
      サーバーのメトリック名称を示します。

    • desc
      サーバーのメトリックの説明です。
      この設定値が、Chrome の 開発者ツールに表示されます。

    • dur
      duration の略でかかった時間を示します。
      単位は ms で、Python の timeモジュールで取得できる duration は 秒になるため 1000 倍する必要があります。

  • settings.py
    MIDDLEARE_CLASSES の一番上に作成した middleware を記載します。

    MIDDLEWARE_CLASSES = (
        "mezzanine_extentions.middleware.StatsMiddleware",
    


Google Analytics に 送信する

Google Analytics に 設定した Server-Timing の値を送信します。
当サイトは、Google Tag Manager 経由で Google Analytics のタグ配信を行なっているため、Google Tag Manager で設定を行いました。

  • W3C example JavaScript
    そもそもどのようにして、JavaScript からアクセスできるかわからず、まず W3C example JavaScript を確認しました。
    navigation現在開いているページの HTML の Server-Timing 、resource で、サブリソースのServer-Timingが取得できます。

    // serverTiming entries can live on 'navigation' and 'resource' entries
    for (const entryType of ['navigation', 'resource']) {
      for (const {name: url, serverTiming} of performance.getEntriesByType(entryType)) {
        // iterate over the serverTiming array
        for (const {name, duration, description} of serverTiming) {
          // we only care about "slow" ones
          if (duration > 200) {
            console.info('Slow server-timing entry =',
              JSON.stringify({url, entryType, name, duration, description}, null, 2))
          }
        }
      }
    }
    
    if (duration > 200) { if文を削除してコードを実行すると、以下のような情報が取得できます。
    Slow server-timing entry = {
      "url": "https://www.monotalk.xyz/blog/Deal-with-http-response-headers-warnings-in-security-headers/",
      "entryType": "navigation",
      "name": "res",
      "duration": 26,
      "description": "Server app response time"
    }
    VM1355:7 Slow server-timing entry = {
      "url": "https://www.monotalk.xyz/report/",
      "entryType": "resource",
      "name": "res",
      "duration": 119,
      "description": "Server app response time"
    }
    VM1355:7 Slow server-timing entry = {
      "url": "https://www.monotalk.xyz/report/",
      "entryType": "resource",
      "name": "res",
      "duration": 105,
      "description": "Server app response time"
    }
    VM1355:7 Slow server-timing entry = {
      "url": "https://www.monotalk.xyz/report/",
      "entryType": "resource",
      "name": "res",
      "duration": 108,
      "description": "Server app response time"
    }
    VM1355:7 Slow server-timing entry = {
      "url": "https://www.monotalk.xyz/report/",
      "entryType": "resource",
      "name": "res",
      "duration": 120,
      "description": "Server app response time"
    }
    VM1355:7 Slow server-timing entry = {
      "url": "https://www.monotalk.xyz/blog/qualys-ssl-server-test-%E3%82%92%E5%AE%9F%E8%A1%8C%E3%81%97%E5%87%BA%E5%8A%9B%E3%81%95%E3%82%8C%E3%82%8B%E8%AD%A6%E5%91%8A%E3%81%AB%E5%AF%BE%E5%87%A6%E3%81%99%E3%82%8B/",
      "entryType": "resource",
      "name": "res",
      "duration": 21,
      "description": "Server app response time"
    }
    

  • severTiming.js
    Google Tag Manager では、以下のようなコードを カスタム JavaScript 変数として設定しました。

    function () {
        var serverTiming = performance.getEntriesByType('navigation')[0].serverTiming;
        for (var i = 0; i < serverTiming.length; i++) {
            if (serverTiming[i].name == "res") {
                return serverTiming[i].duration;
            }
        }
        return undefined;
    }
    

  • Google Analytics 変数に、カスタムディメンションを追加
    カスタムディメンションの20番に、serverTiming設定しました。
    2019-03-23 3.01.27.png - Google ドライブ


django-server-timing について

Server Timing を設定できる Django の plugin として、vtemian/django-server-timing: Django middleware and utils that add Server-Timing header存在します。
計測対象の View にデコレータを付与して使うので、このサイトには適用は難しいので使用しませんでしたが、ユースケースに合うなら使用を検討してもいいかもしれません。


参考

以下、参考にしました。

以上です。

コメント