同期・非同期

JavaScript

cssを非同期で読み込んでクリティカルリクエストチェーンを回避した結果

更新日:2023/02/24

このサイトはWordPressですが、テーマを自作しています。
そのためファーストビューで使用するクリティカルcssをインラインで書き込む等の処置をしています。

しかし、PageSpeed InsightsでWebページの読み込み速度を採点してみたところ、cssの読み込みで問題を指摘されてしまいました。

対処としてcssを非同期読み込みしました。
その理由と方法、変更結果についてお伝えします。

 

クリティカルリクエストチェーンを回避してください

PageSpeed Insightsは携帯電話とデスクトップの二つのプラットホームでWebページの読み込み速度を採点してくれます。

デスクトップはそれなりに良い点数を得ることができましたが、携帯電話は40点くらいで良い結果とはいえません。
ただ、問題点を見ていると90%くらいが AdSense によるものでした。
AdSenseの問題対処は AdSense を停止させるしかないので、現実的ではありません。

その他の問題を探していると、『クリティカルリクエストチェーンを回避してください』というメッセージがありました。

クリティカルリクエストチェーンを回避してください

自分の中では、クリティカルcssのインライン化でクリティカルリクエストチェーンを回避できている、と思っていたのですができていなかったようです。

 

原因

僕のサイトでは、クリティカルcss以外のcssは次のようなタグで読み込んでいました。

<link rel="stylesheet" href="https://ドメイン/xxx.css" type="text/css" />

いわゆる、普通に読み込んでいるだけですね。
普通に読み込むと、cssファイルがサーバーから読み込まれてからブラウザの描画が開始されます。

ファーストビュー表示の高速化のためにクリティカルcssのみを抜き出しても、外部cssの読み込みを待っているのでは意味が無いのです。

クリティカルリクエストチェーンの回避とは、描画前に外部css読み込みを待たないようにすることを指します。

 

対処:外部cssの非同期読み込み

対処法は二つあります。

一つ目は、htmlの機能を上手く使って非同期に読み込み、描画後にcssを有効化します。
二つ目は、JavaScriptで描画後にcssファイルを読み込む方法です。

おススメは一つ目です。

二つ目は描画後に読み込みが開始しますが、一つ目はブラウザの処理と並行して読み込みます。
結果として、一つ目の方が読み込み終了が速いからです。

そのため二つ目の方法は、参考として紹介します。

非同期に読み込む

次のように記述すると、cssファイルを非同期で読み込むことができます。

<link media="print" onload="this.media='all'" rel="stylesheet" href="https://ドメイン/xxx.css" type="text/css" />
<noscript><link rel="stylesheet" href="https://ドメイン/xxx.css" type="text/css" /></noscript>

1行目は普通の書き方に、media="print" onload="this.media='all'" が追加されています。

media="print"は、『このcssは印刷時に使用します』という意味です。
これにより読み込みは並列でおこなわれますが、Webページの表示は印刷ではないので無効です。
そのため、読み込みが完了していなくてもファーストビューの描画が行われます。

onload="this.media='all'"は、全てのファイルの読み込みが終わったときに呼び出されるJavaScriptコードです。
これにより、media="print"media="all"に変更されます。
allは全てという意味です。
結果として、cssが有効化されます。

2行目は、ブラウザの設定でJavaScriptが無効化されている時に使用されます。
JavaScriptが使用できるときは、無視されます。
1行目のonload="this.media='all'"は、JavaScriptが無効化されていると無視されるのでcssが有効化されません。
それを避けるための措置です。

上記の方法は非同期のような動作をさせているだけです。

実はlinkタグには非同期読み込みの機能があります。
次のように記述します。

<link rel="preload" onload="this.rel='stylesheet'" href="https://ドメイン/xxx.css" type="text/css" />
<noscript><link rel="stylesheet" href="https://ドメイン/xxx.css" type="text/css" /></noscript>

rel="preload"で非同期に読み込みます。
しかし読み込むだけなので、こちらもonloadで有効化する必要があります。

本来ならrel="preload"を使用すべきですが、現状では対応していないブラウザがあるため今のところは使用を控えた方がいいです。

参考:JavaScriptで読み込む

次のJavaScriptコードで、ファーストビューの表示準備ができた後にcssファイルを読み込みことができます。

window.asyncloadCss = styleFile =>
    document.addEventListener( "load" , ()=>{
        const link = document.childElementCount( "link" );
        link.rel = "stylesheet";
        link.href = styleFile;
        link.media = "all";
        document.head.appendChild( link );
    });

asyncloadCss( "https://ドメイン名/xxx.css" );

 

適用した結果

外部cssを非同期読み込みに変更してPageSpeed Insightsで採点してみました。
変更前と変更後を比較してみます。

■変更前
クリティカルリクエストチェーンを回避してください
■変更後
非同期読み込み 変更結果 PageSpeed Insights

『クリティカルリクエストチェーンを回避してください』というメッセージが消えました。
成功ですね。

その他の項目もいろいろ変化していますが、AdSenseの問題なのか今回の変更の影響なのか切り分けが難しいものもあります。

深追いしても効果が薄そうなので、これで終了です。

なお、採点は69点でした。

 PageSpeed Insights 69点

AdSenceさんに頑張ってほしいです。

ついでにデスクトップを確認したら、なんと100点でした。

 PageSpeed Insights 100点

驚きです。

更新日:2023/02/24

書いた人(管理人):けーちゃん

スポンサーリンク

記事の内容について

null

こんにちはけーちゃんです。
説明するのって難しいですね。

「なんか言ってることおかしくない?」
たぶん、こんなご意見あると思います。

裏付けを取りながら記事を作成していますが、僕の勘違いだったり、そもそも情報源の内容が間違えていたりで、正確でないことが多いと思います。
そんなときは、ご意見もらえたら嬉しいです。

掲載コードについては事前に動作確認をしていますが、貼り付け後に体裁を整えるなどをした結果動作しないものになっていることがあります。
生暖かい視線でスルーするか、ご指摘ください。

ご意見、ご指摘はこちら。
https://note.affi-sapo-sv.com/info.php

 

このサイトは、リンクフリーです。大歓迎です。