スポンサーリンク

全ページの PageSpeed Insights の結果からモバイルの LCP を改善する

moon_and_rabiit
記事内に広告が含まれています。
スポンサーリンク

全てのページの PageSpeed Insights の結果を取得する

以前に複数ページの PageSpeed Insights の結果を一括で取得する psi-score-collector を使用してみました。複数ページを一度に測定できるので便利です。

この時には LiteSpeed Cache に関するページにトップページ加えて、計6ページの結果を集計しました。

今回はトップページを含めた全てのページの PageSpeed Insights の結果を取得し、現在の状態を把握したいと思います。

スポンサーリンク

sitemap.xml から全てのページの URL を取得

私の WordPress の日記も 70 記事を超えましたので、手作業で URL を収集するのは不可能ではありませんが大変になってきました。私のサイトではサイトマップを作成する XML Sitemap & Google News プラグインを導入しています。

自動的に作成されている sitemap.xml から URL を抜き出して、対象の URL リストを作成します。

今回、測定対象とするページとサイトマップの xml ファイルは以下の通りです。

No.ページ種類サイトマップの xml ファイル
1トップページsitemap-root.xml
2日記ページsitemap-posttype-post.2023.xml
sitemap.xml のファイル名

この二つの xml ファイルを WSL2 Ubuntu 上にダウンロードします。

$ wget https://hiro20180901.com/sitemap-root.xml
$ wget https://hiro20180901.com/sitemap-posttype-post.2023.xml

xml の中身を確認すると、URL は以下のように記録されています。一部を抜き出します。

<url>
     <loc>https://hiro20180901.com/</loc>
     <priority>1.0</priority>
     <lastmod>2023-08-09T22:00:00+09:00</lastmod>
</url>

<loc> タグで囲まれた部分に URL が記録されていますので、以下のページを参考に grep と sed で抜き出します。

$ cat *xml | grep -o "<loc[^>]*>[^<]*</loc>" | sed -e "s/<loc>\(.*\)<\/loc>/\1/" | sort > url_list.txt

$ head -n 5 url_list.txt
 https://hiro20180901.com/
 https://hiro20180901.com/2023/01/28/start-new-dialy/
 https://hiro20180901.com/2023/01/28/why-use-wordpress/
 https://hiro20180901.com/2023/01/29/lolipop-muumuu-wordpress-setting/
 https://hiro20180901.com/2023/01/30/use-litespeed-cache-on-wordpress/$ wc -l url_list.txt

$ wc -l url_list.txt
72 url_list.txt

トップページを含めて 72 ページあります。これで測定対象の URL リストが作成できました。

psi-score-collector で結果を取得

以前に使用した psi-score-collector と、前項で作成した URL リストを組み合わせて、少し手直しして実行します。psi-score-collector については、以下の記事を参照ください。

psi-score-collector の出力を CSV に変更

psi-score-collector の出力が CSV になるように一部修正しました。main_csv.py という名称で作成しました。

--- main.py	2023-05-03 20:03:58.326204822 +0900
+++ main_csv.py	2023-05-03 20:02:43.816221492 +0900
@@ -37,7 +37,8 @@
     'desktop': 'Desktop'
   }
 
-  print(f'[ {device_name[device]} ]')
+  print(f'{url}',end=', ')
+  print(f'{device_name[device]}', end=', ')
 
   payload['strategy'] = device
   url_name = api_url + "?url=" + url
@@ -68,7 +69,6 @@
     lab_lcp_scores.append(lab_data_scores['lcp'])
     lab_cls_scores.append(lab_data_scores['cls'])
     scores.append(displayed_score)
-    print(displayed_score, end=' ')
 
   average_scores = calculate_average(scores)
   average_lab_fcp_scores = calculate_average(lab_fcp_scores)
@@ -76,28 +76,22 @@
   average_lab_si_scores = calculate_average(lab_si_scores)
   average_lab_lcp_scores = calculate_average(lab_lcp_scores)
   average_lab_cls_scores = calculate_average(lab_cls_scores)
-  print('\nAvg. {main} (min {min} max {max} )' \
-    .format(
-      main=average_scores['main'],
-      min=average_scores['min'],
-      max=average_scores['max']
-    ))
-  print('(Labo Data)', end=' ')
-  print('FCP: {main} s'.format(main=average_lab_fcp_scores['main']), end=', ')
-  print('TBT: {main} s'.format(main=average_lab_tbt_scores['main']), end=', ')
-  print('SI : {main} s'.format(main=average_lab_si_scores['main']), end=', ')
-  print('LCP: {main} s'.format(main=average_lab_lcp_scores['main']), end=', ')
-  print('CLS: {main}'.format(main=average_lab_cls_scores['main']))
+
+  print('{main} '.format(main=average_scores['main']),end=', ')
+  print('{main} '.format(main=average_lab_fcp_scores['main']), end=', ')
+  print('{main} '.format(main=average_lab_tbt_scores['main']), end=', ')
+  print('{main} '.format(main=average_lab_si_scores['main']), end=', ')
+  print('{main} '.format(main=average_lab_lcp_scores['main']), end=', ')
+  print('{main} '.format(main=average_lab_cls_scores['main']))
 
 print('\n '.join(map(str, url_list)))
 print(f' measuring...({measurement_count} times)')
 
+print('URL, Device, PSI, FCP, TBT, SI, LCP, CLS')
+
 for i, url in enumerate(url_list):
-  print(f'\n({i + 1}/{len(url_list)}) {url}')
 
   measure('mobile')
   measure('desktop')
 
-  print('\n' + '=' * 60)
-
 print('\nFinish!!')

URL, Device, PSI, FCP, TBT, SI, LCP, CLS の順に表示します。

url_list.txt の一部手直し

取得しておいた url_list.txt を psi-score-collector の python のリストで使用できる形に直す為に、先頭に「'」を、行末に「',」を追加し、最終行のみコンマを除去しました。

# 測定対象 URL
url_list = [
  'https://hiro20180901.com/',
  'https://hiro20180901.com/2023/01/28/start-new-dialy/',
  ... (snip) ...
  'https://hiro20180901.com/2023/08/08/cocoon-2-6-4-update/',
  'https://hiro20180901.com/2023/08/09/wordpress-6-3-update/'
]

sed を使っても良いですが、私は vim の範囲指定の置換を使って編集しました。

実行スクリプトの変更と実行

変更した main_csv.py を使用するように、実行スクリプトを変更します。

$ cat get_psi_csv.sh
poetry run python3 main_csv.py

実行しながら画面表示をするように、tee を使用します。

$ ./get_psi_csv.sh | tee psi_result.csv

出来た psi_results.csv を Excel 等で開き集計、分析します。

全てのページの PageSpeed Insights の結果

URL 表記だと長い文字列になりますので番号を振りました。トップページが No.1、以降は古い順番に No.2 ~ 72 になります。No.72 が最新のページになります。

QUIC.cloud の CDN の影響を調べるために、CDN ON と CDN Bypass で結果を比較しました。

スコアにはばらつきがありますので、6回測定して最悪値を除外した5回の平均値を求めました。

Desktop と Mobile の平均 (QUIC.clound CDN ON)

QUIC.cloud CDN が有効な状態での結果です。Region は North America / Europe / Asia のみ有効にしています。赤字強調部分は Green Range を外れている箇所です。

Avg.Max.Min.Green
Range
PSI99.6100.097.890-100
FCP0.5050.6290.4370-1.80
TBT0.0000.0030.0000-0.20
SI0.7010.9100.5470-3.40
LCP0.7441.0480.5690-2.50
CLS0.0000.0000.0000-0.10
PageSpeed Insights Desktop の Avg. Max. Min.
Avg.Max.Min.Green
Range
PSI96.098.692.690-100
FCP1.4931.7411.2720-1.80
TBT0.0250.1110.0080-0.20
SI1.9132.9511.5130-3.40
LCP2.6203.1492.0550-2.50
CLS0.0000.0000.0000-0.10
PageSpeed Insights Mobile の Avg. Max. Min.
  • Desktop は全ての項目で Green Range に入っていました。幾度か測定すると、稀に PSI < 90 のページもありますが、再測定すると PSI > 90 となりますので、一時的な現象かと考えています。(CDN で振り分けられる影響でしょうか)
  • Mobile は PSI は全てのページで Green Range に入っていました。しかし、LCP (Largest Contentful Paint) は 2.50 未満の Green Range に対して平均で 2.62、最大で 3.15 と外れていました。
  • CLS (Cumulative Layout Shift) は全てのページで 0 でした。

トップページは良好な結果を維持していますが、全てのページを調べると、PSI は Desktop / Mobile 共に良好ですが、Mobile の LCP がイマイチ、という結果でした。

Desktop と Mobile の平均 (QUIC.clound CDN Bypass)

QUIC.clound の CDN を Bypass して、LOLIPOP! レンタルサーバーに直接接続した場合の結果です。赤字強調部分は Green Range を外れている箇所です。

Avg.Max.Min.Green
Range
PSI100.0100.099.490-100
FCP0.3890.4500.3290-1.80
TBT0.0000.0000.0000-0.20
SI0.4490.5370.3480-3.40
LCP0.6250.7960.4570-2.50
CLS0.0000.0000.0000-0.10
PageSpeed Insights Desktop の Avg. Max. Min.
Avg.Max.Min.Green
Range
PSI96.799.090.890-100
FCP1.3291.5261.1010-1.80
TBT0.0160.0410.0030-0.20
SI1.3381.5491.1010-3.40
LCP2.5242.9992.0750-2.50
CLS0.0000.0000.0000-0.10
PageSpeed Insights Mobile の Avg. Max. Min.
  • 傾向は CDN を使用している場合と大きく変わりませんが、各項目共にスコアが向上しています。
  • Mobile の LCP (Largest Contentful Paint) は 2.50 未満の Green Range に対して平均で 2.52、最大で 3.00 と外れていました。

Desktop / Mobile 共に PageSpeed Insights の結果は向上していますが、Mobile の LCP が Green Range を外れているのは同じ結果でした。

Mobile のページの LCP の結果の比較 (CDN ON / Bypass)

Mobile の LCP の分布を以下に示します。

RangeCDN ONCDN Bypass
0.00-2.3066
2.30-2.502529
2.50-2.6052
2.60-2.70314
2.70-2.801213
2.80-2.90104
2.90-3.0094
3.00-20
CDN ON / Bypass での LCP の違い
  • CDN ON の時と比べて、CDN を Bypass した時には、Green Range の LCP < 2.50 のページが増加している。
  • LCP > 2.50 の領域でも、ピークが 2.70 ~ 3.00 から、2.60 ~ 2.70 に下がっている

LCP の平均値、最大値も下がっていましたが、CDN を Bypass する事で LCP の向上は見られます。それでも Green Range に入りませんので、その原因ついて調べてみます。

Mobile の LCP の良いページと悪いページの比較

Mobile の LCP の良いページと悪いページを比較します。QUIC.cloud CDN Bypass の結果です。

No.PSIFCPTBTSILCPCLS
Green
Range
90-1000-1.800-0.200-3.400-2.500-0.10
199.01.110.011.312.080.000
7299.01.170.021.172.090.000
5499.01.190.021.222.160.000
4095.61.180.011.202.250.000
298.01.130.011.132.250.000
4995.01.430.011.432.860.000
4894.21.430.041.452.910.000
2894.81.430.011.442.930.000
6994.41.430.011.432.930.000
5094.01.430.011.453.000.000
Mobile LCP のスコアの上位・下位 5ページの PageSpeed Insights の結果

LCP のスコアの良いページ :

LCP のスコアの悪いページ :

これらの二種類のページについて、PageSpeed Insights と Chrome デベロッパーツールの Lighthouse の Mobile 版を使用して LCP に影響する項目について調べました。

Mobile の LCP スコア改善の為の試行

上記のページを調べると、Chrome デベロッパーツールの Lighthouse では LCP に影響する項目として、JavaScript の Google Tag Manager (gtm.js) と jQuery (jquery.min.js) の読み込みに時間を要している事が確認できました。そこで、LiteSpeed Cache の設定を変更してみる事にしました。

Google Tag Manager を無効

AMP 機能を使用していた際に使い始めていましたが、あまり活用できていなかった (使い方を理解できなかった) 為に無効にしました。

Google タグマネージャーを無効

LiteSpeed Cache : DNS プリフェッチ制御 OFF -> ON

LiteSpeed Cache の設定 -> ページの最適化 -> [3] HTML にある、DNS プリフェッチ制御を ON にしました。「ドキュメント内の全ての URL に対して、DNS プリフェッチ (先読み) 」するようです。

ページの最適化 -> [3] HTML 内の DNS プリフェッチ制御をオン

DNS の応答が遅れる事による読み込みの遅れを防止する狙いです。

Cocoon テーマの側にも同様の設定があり、事前に読み込まれていると考えていましたが、LiteSpeed Cache の側でも有効にしてみます。

LiteSpeed Cache : gtm.js と jquery.min.js を遅延読み込み

LiteSpeed Cache の設定 -> ページの最適化 -> [8] (JSの) チューニング画面で、「JS 除外」と「JS Deferred / Delayed 除く」の項目から、gtm.js と jquery.js、jquery.min.js を消去して、遅延読み込みするようにしました。

[8] チューニングの JS 除外と
JS Deferred / Delayed 除く変更前
[8] チューニングの JS 除外と
JS Deferred / Delayed 除く 変更後

DNS の応答が速くなったとしても読み込みに時間を要す可能性もあります。ググると WordPress で jquery.min.js を遅延読み込みされている方もいましたので、とりあえず変更して様子を見てみます。

副作用が大きいかもしれませんので、変更後には動作に変な箇所がないか注意します。

LiteSpeed Cache : 生成された CSS、JavaScript とキャッシュのパージ

今回は「ページの最適化」の HTML / JavaScript 周り色々と変更しましたので、これを機に クリティカル CSS、ユニーク CSS、CSS や JavaScript の minify を含む、LiteSpeed Cache で生成された CSS と JavaScript をパージしてみます。CSS と JavaScript をパージしますので、同時にキャッシュもパージします。

LiteSpeed Cache のツールボックス内で、以下のアイコンを押してパージしました。

一時的に PageSpeed Insights の結果が低下すると予想しています。また、ページの最適化の今月の残りも少ないので、元通りに戻るまでは2カ月位要するのではないかとも考えています。

画像周りは影響ないと思いますので、そのまま使用します。

まとめ

psi-score-collector の改変版を使用して、トップページを含む全72ページの Desktop / Mobile の PageSpeed Insights の結果を集計しました。

Desktop の結果は全ての項目で Green Range でしたが、Mobile では LCP (Largest Contentful Paint) が悪い結果でした。

Mobile の低速な回線では JavaScript (gtm.js, jquery.min.js) の読み込みに時間を要しているようでしたので、

  • Google Tag Manager を無効
  • LiteSpeed Cache の DNS プリフェッチ制御を有効
  • LiteSpeed Cache の JavaScript (jquery.min.js) を遅延読み込みに変更
  • LiteSpeed Cache のキャッシュと CCSS, UCSS, JS を一旦パージ

という対処を取ってみました。

数ページを見た感じでは、極端な PageSpeed Insights のスコアの低下は見られませんでした。暫く時間を置いてから、再度、全ページの PageSpeed Insights のスコアを取得し、比較してみたいと思います。

できれば自動で収集して記録・集計するようにしたいですが、もう少し勉強が必要です。

今回のアイキャッチ画像

月夜のウサギを生成しました。今回は1回目の生成で想像していた絵が生成できました。

コメント

タイトルとURLをコピーしました