PageSpeed Insightsの長時間タスクをCSS・JS・DOMから検証
これまでPageSpeed Insightsで指摘される項目を減らすため、サイトの読み込み速度を改善する対策を続けてきました。しかし、「長時間タスク」「強制リフロー」「DOM数の削減」については、原因が分からず対策できないままでした。
これ以上、読み込みを速くする方法が思いつかなくなったため、この3つの指摘をなくすことができれば、PageSpeed Insightsのスコアをさらに改善できるのではないかと考え、原因を調べることにしました。
まず、Chromeのデベロッパーツールを使って、サイトの読み込み中に何が起きているのかを調べました。当初はローカル環境のWordPressで測定していましたが、思っていた以上にWordPressによる速度低下が大きかったため、Simply Staticプラグインで静的ファイルを作成し、静的サイトの状態でも測定することにしました。
そこで分かったのは、実際のDOM数はそれほど多くないにもかかわらず、ページの読み込み途中でレイアウトが変化し、そのたびにレイアウト計算や描画が繰り返されていたことです。これが、DOM数が多いと判断される原因の一つになっていました。
しかし、何がレイアウトの変化を引き起こしているのか、すぐには分かりませんでした。そこで、ページを構成する要素を一つずつ削除したり、逆に追加したりしながら測定を繰り返し、どの要素が影響しているのかを調べていきました。
目次OpenClose
フォントについてCSSについてJavaScriptについて長時間タスクの指摘が消えるフォントについて
JS、CSS、ローカルに保存したWebフォントをそれぞれ切り分けて測定したところ、フォントを削除するとLayoutの時間が大幅に減少しました。
HTMLを読み込んでページを表示した後にWebフォントが読み込まれることで、文字の表示が変わり、それに伴ってレイアウト計算や描画が再び発生していたようです。
フォントはあらかじめPreloadし、font-display: optionalを指定しておけば、非同期で読み込まれるためCLSも発生せず、ページの表示速度にもほとんど影響しないと考えていました。しかし、実際に測定してみると、フォントの読み込みもLayoutに大きな影響を与えることが分かりました。
CSSについて
ファーストビューに必要なCSSをインラインで読み込ませると、ページを表示するまでのCLS対策に効果があります。一方で、残りのCSSを通常どおり同期的に読み込ませると、レンダリングをブロックするため、PageSpeed Insightsで指摘を受けます。
そこで、残りのCSSを非同期で読み込ませる方法を試しました。ただし、CSSを読み込む順番によっては、最初に表示したときと後からCSSが適用されたときでレイアウトが変わり、再計算や再描画が発生します。
CSSの記述順も重要です。ページの上部で使用する要素のCSSから、できるだけページの構成順に記述するようにしました。ページ全体に関係するCSSがファイルの最後にまとめられていると、後からそのCSSが適用されることで、再計算や再描画の原因になる場合があります。
CSSによる再計算や再描画を減らすことは、今回の測定では特に効果が大きく、長時間タスクを減らすうえで重要でした。
また、CSSセレクタにも注意が必要です。:has()や:last-childなどは、状況によってはブラウザが適用対象を探す処理の負荷が高くなります。特に:has()は複雑な条件で使用すると負荷が大きくなるため、可能な場合はPHP側で出力するHTMLを変えるなどして、使用を減らしました。
backdrop-filter: blur()など、描画処理の負荷が高いプロパティの使用にも注意が必要です。
CSSセレクタは、タグ名だけで指定するよりも、必要な要素にクラスを付けて指定するようにしました。例えば、リセットCSSで次のようにolやul全体を指定するのではなく、必要な要素に個別にクラスを付けてCSSを指定します。
ol,
ul {
margin: 0;
padding: 0;
}
pやh2などについても、必要に応じてクラスを付けて指定しました。どの要素にCSSを適用するのかをできるだけ明確にすることで、ブラウザがCSSの適用対象を探す処理を減らせると考えました。
さらに、ページ下部の要素にはcontent-visibility: autoとcontain-intrinsic-sizeを使用しました。これにより、表示領域から離れた要素については、実際に表示する必要が近づくまでレイアウトや描画の処理を省略できます。
ただし、loading="lazy"と同じように、表示領域からかなり離れた場所にあっても処理が始まることがあります。そのため、content-visibility: autoを使用する要素の位置には注意が必要です。
JavaScriptについて
JavaScriptはbodyの閉じタグの直前に記述するのが良いと思っていましたが、今回の測定ではCSSと同じように、できるだけ早い段階で読み込ませたほうがLayoutへの影響を抑えられることが分かりました。
CSSを読み込んだ後にJavaScriptをdefer付きで読み込むように変更しました。JavaScriptをhead内に移すことで、具体的な仕組みをうまく説明できるほどの知識はありませんが、測定結果を見る限り、bodyの閉じタグの直前に読み込むよりもLayoutの発生が少なくなりました。
また、JavaScriptを読み込んだだけでDOMを変更する処理はできるだけ行わないようにしました。ファーストビュー以外の場所でDOMを変更する必要がある場合は、スクロールをきっかけに処理を実行するようにして、ページの初期表示への影響を遅らせました。
これは、AdSenseやGoogle Analyticsなどの外部サービスについても同様です。初期表示に必要のない処理は、できるだけページの表示後に実行するようにしました。
長時間タスクの指摘が消える

今回の対策を続けた結果、初めてPageSpeed Insightsから「長時間タスク」の指摘がなくなりました。携帯電話での測定でも、FCP 0.8秒、LCP 0.9秒、Speed Index 0.8秒となり、それぞれ1秒を切る結果になりました。
DOM数、CSS、JavaScriptは、少ないほどページの表示にかかる時間を短くできます。しかし、単純に削ればよいというものではないため、どこまで減らすかの判断は難しいところです。
今回の測定を通して分かったのは、DOMそのものの数を減らすだけでなく、ページの読み込み途中でレイアウト計算や描画が繰り返されることを減らすことも重要だということです。CSSやJavaScriptの読み込み方や処理を工夫することで、このような再計算や再描画を減らせることが分かりました。
最後までお読みいただき、誠にありがとうございます。