Pathee engineering blog

世界をしなやかに変えるエンジニアたちのブログ

lighthouseの結果をSlackに流してみた

Patheeメディアチームエンジニアの makoll です。 弊社運営MediaのPatheeについて、 社内で応答性能やSEOスコアの話題になったので、 lighthouseの結果を毎日Slackに投げる仕組みを作りました。

f:id:pathee:20190606104933p:plain
lighthouseのイメージ

  • ステップ

    1. Google謹製のlighthouseCLIをインストールする
    2. lighthouseの結果をファイルとして取得する
    3. お好きな言語でファイルの内容を見やすいように加工する
    4. cronなりでお好きなタイミングで実行して、どうぞ
  • 環境

    • OS: CentOS7.1
    • Node: v10.5.0
    • Python: 3.6.6

コマンドや言語は適宜読み替えてください。

それでは実践に行きましょう。

1. Google謹製のlighthouseCLIをインストールする

sudo yum install -y chromium
npm i -g lighthouse

2. lighthouseの結果をファイルとして取得する

TODAY=$(date "+%Y%m%d")
URL="https://pathee.com/region/tokyo/shinjuku/mizugi.html"    
FILE=/path/to/data/report_${TODAY}.json
lighthouse ${URL} --output-path=${FILE} --output=json --chrome-flags="--headless --no-sandbox --disable-gpu" --quiet    

--chrome-flagsオプションを指定しないと、 ChromeGUIが起動するのを待ち続けて終了します。

3. お好きな言語でファイルの内容を見やすいように加工する

例はpythonです。

import json
import slackweb  # slackwebのインストールが必要です
import sys

args = sys.argv
today = args[1]
slack_webhook_url = 'slack incoming webhook URL'
input_file_name = f'/path/to/data/report_{today}.json'
metrics = ['performance', 'accessibility', 'best-practices', 'seo']  # 'pwa'


def change_inline(message: str) -> str:
    return f'```{message}```'


with open(input_file_name) as f:
    report = json.loads(f.read())
    fetchTime = report.get('fetchTime')
    categories = report.get('categories')
    audits = report.get('audits')

summary_audit_messages = []
for metric in metrics:
    score = int(categories.get(metric).get('score') * 100)
    temp_message = f'{metric}: {str(score)}'
    summary_audit_messages.append(temp_message)
joined_summary_audit_messages = change_inline('\n'.join(summary_audit_messages))
summary_audit_message = f'`{fetchTime}`の`新宿 水着`のlighthouseの結果だよ\n{joined_summary_audit_messages}'

audit_messages = []
for metric in metrics:
    audit_refs = categories.get(metric).get('auditRefs')
    audit_refs = filter(lambda x: x['weight'] != 0, audit_refs)
    audit_refs = sorted(audit_refs, key=lambda x: x['weight'], reverse=True)

    each_audit_messages = []
    for audit in audit_refs:
        audit_name = audit.get('id')
        weight = audit.get('weight')
        score = int(audits.get(audit_name).get('score') * 100)
        temp_message = f'{audit_name}({weight}): {score}'
        each_audit_messages.append(temp_message)

    joined_each_audit_messages = change_inline('\n'.join(each_audit_messages))
    audit_messages.append(f'`{metric}`の詳細だよ\n{joined_each_audit_messages}')
audit_message = '\n'.join(audit_messages)

slack = slackweb.Slack(url=slack_webhook_url)
message = f'{summary_audit_message}\n{audit_message}'
slack.notify(text=message, username='lighthouse拾ってくる君', icon_emoji=':db:')

4. 実行

こんな結果になります。

f:id:pathee:20190530172055p:plain:w500

seoは悪くないですが、performanceとaccessibilityは改善したいところです。

ポイント

各category > auditRefsのweightが0ではない項目を表示しているところです。
カテゴリの代表スコアは各詳細のscoreとweightによって算出されるため、 weight=0のscoreを改善しても代表スコアは変わりません。

このページでは PageSpeed Insightsのパフォーマンススコアの算出方法について説明していますが、 accessibilityなど他のメトリクスも同じ計算式のようです。

各指標について

改善について

weightが0の項目を改善してもスコアには反映されないため、 それ以外の項目から改善していくのが良いと思います。
とはいえUX改善の参考になりますし、 今後weightが付与される可能性もあるので、 可能な限りscoreがつくように改善していきたいところです。