全ブラウザ対応!preload で CSS を非同期で読み込み高速化

Akira

福岡在住ウェブデザイナー。Web サイト制作に役立つ情報を紹介しています。AMP が大好き。

FacebookTwitter で記事の更新をお知らせしています。

CSS は、レンダリングをブロックします。

サイトを高速にするには、重要ではない CSS を非同期で読み込むことが効果的。

一般的には JavaScript を使い非同期で読み込みますが、もう 1 つ方法があります。

それは HTML に記述するだけの <link rel="preload"> での読み込み。

現在 Chrome しか対応していませんが、Polyfill の loadCSS を使うことで全ブラウザに対応できます。

その loadCSS の使い方の説明です。

<link rel="preload"> って何?と思われた方は、rel=”preload” によるコンテンツの先読み、または Preload — 事前読み込みをご参考ください。

全ブラウザ対応の loadCSS

loadCSS は、Filament Group が開発した JavaScript の Polyfill です。

通常 <link rel="preload"> に対応していないブラウザでは、例え記述をしても CSS は非同期で読み込まれません。

それに対し loadCSS は、対応していないブラウザでも CSS を非同期で読み込みます。

仕組みは、まずブラウザが <link rel="preload"> に対応しているかを判定。

対応していれば、何もしません。

対応していなければ、一時的に media 属性を操作し回避方法を適用。そして、CSS を動的に非同期で読み込みます。

これによりブラウザ対応を気にせず、<link rel="preload"> を使えるようになります。

<link rel="preload"> は、執筆時点で Chrome しか対応していません。

Can I use… : preload

主要ブラウザは対応予定ですが、開発が停止された IE は対応しません。IE のシェアが高い日本では、これからも <link rel="preload"> を使いにくいのが現状です。

しかし、loadCSS を使うことで、今すぐにでも CSS を非同期で読み込めます。

loadCSS の使い方

loadCSS の使い方は、非常に簡単です。

example.css というスタイルシートを読み込む例として説明します。

通常は、<head> タグに下記のように記述します。

<link rel="stylesheet" href="example.css">

一方、loadCSS を使う場合は、まず下記のように <head> タグに記述します。

<link rel="preload" href="example.css" as="style" onload="this.onload=null;this.rel='stylesheet'">
<noscript><link rel="stylesheet" href="example.css"></noscript>

次に、上記の HTML の下に cssrelpreload.js をまるっとコピペします。

サイトで縮小化処理をしていない場合は、Online JavaScript/CSS/HTML Compressor などで縮小してから貼り付けるといいかもしれません。

<link rel="preload" href="example.css" as="style" onload="this.onload=null;this.rel='stylesheet'">
<noscript><link rel="stylesheet" href="example.css"></noscript>
<script>
/*! loadCSS. [c]2017 Filament Group, Inc. MIT License */
ここに縮小したcssrelpreload.jsを貼り付ける
</script>

5 行目に縮小した cssrelpreload.js を貼り付けます。

これで終わり。すごく簡単。

これだけで CSS がレンダリングをブロックしなくなり、サイトが速くなります。

複数の <link rel="preload"> がある場合は、それぞれの後ろに cssrelpreload.js を付けると最高の結果を得られるとのこと。

詳しい使い方や説明は、GitHub でご確認ください。

WordPress プラグインに適用

WordPress をお使いであれば、プラグインの CSS も loadCSS で読み込むとサイトが高速化します。

多くの WordPress サイトが使っている Contact Form 7 を例にあげます。

id が 10 の固定ページに、Contact Form 7 でお問い合わせページを作っているとします。

まず子テーマの functions.php に、以下のコードを追加します。

add_action( 'wp_enqueue_scripts', function() {
  wp_dequeue_style( 'contact-form-7' );
  if ( is_page( 10 ) === false ) {
    wp_dequeue_script( 'contact-form-7' );
  }
});

Contact Form 7 のスタイルシートの読み込みを全ページで停止し、スクリプトはお問い合わせページ以外では読み込まない内容です。

wp_dequeue_style で指定する contact-form-7 のハンドル名は、プラグインのスタイルシートの id から -css を除いたものです。

次に <head> タグ内に、以下のコードを追加します。

<?php
if ( is_page( 10 ) === true ) {
?>
<link rel="preload" href="/wp-content/plugins/contact-form-7/includes/css/styles.css" as="style" onload="this.onload=null;this.rel='stylesheet'">
<noscript><link rel="stylesheet" href="/wp-content/plugins/contact-form-7/includes/css/styles.css"></noscript>
<script>
/*! loadCSS. [c]2017 Filament Group, Inc. MIT License */
ここに縮小したcssrelpreload.jsを貼り付ける
</script>
<?php
}
?>

8 行目に縮小した cssrelpreload.js を貼り付けます。

お問い合わせページでのみ、Contact Form 7 のスタイルシートを loadCSS を使って非同期で読み込んでいます。

ほとんどのプラグインの CSS は、非同期で読み込んでも問題ありません。あらゆるプラグインに適用したいところです。

もっと簡単な media 属性を使った読み込み方法

loadCSS は実装が簡単な上に、様々ケースで有効です。

ただ、<link rel="preload"> に対応していないブラウザのために Polyfill を読み込むことは、無駄に感じるケースもあります。

そこで、loadCSS を開発している Filament Group が、The Simplest Way to Load CSS Asynchronously にて新たな方法を提案しています。

それは、loadCSS を使わずに、たった 1 行の HTML だけで CSS を非同期で読み込む方法。media 属性の使い方が特徴です。

<link rel="stylesheet" href="example.css" media="print" onload="this.media='all'">

<link rel="preload"> との併用も可能です。

loadCSS を使うのか、media 属性を使うのかは、ケースによって使い分けるといいかもしれません。

コメント

  1. WPではどうしたら?

    • WordPress でも、 <head> タグと </head> タグの間に書きます。

      どうやって <head> タグ内に書けばいいのか?とおっしゃっているのであれば、それはテーマによって異なります。 Google アドセンスの審査コードの貼り付けと同じ方法です。

  2. Akira様
    前回お世話になったTOという者です。
    あの説はどうもありがとうございました。
    不勉強のためpreloadのgoogleフォントの非同期読み込みの件は一旦保留することにしました。

    今回、ひとつ質問があるのですが、よろしければご教授いただければ幸いです。

    プラグインのCSSのレンダリングブロックを排除する場合、

    レンダリングブロックを排除したいプラグインのアップロードされているパスを最下記のように差し替えて書けば、本記事のloadCSSは適用できますか?
    agp-font-awesome-collectionというプラグインのCSSのレンダリングブロックを排除したいのですが、
    ————————————————————————————————————————————————–
    【プラグインのlink rel~】


    ————————————————————————————————————————————————–
    【プラグインのサーバー内のパス】
    ①‘URL/wp-content/plugins/agp-font-awesome-collection/assets/repeater/css/style.css?ver=4.9.8′ type=’text/css’ media=’all’ /
    ②‘URL/wp-content/plugins/agp-font-awesome-collection/assets/css/style.min.css?ver=4.9.8′ type=’text/css’ media=’all’ /
    ————————————————————————————————————————————————–
    この①‘②‘を下記のexample.cssの部分に差し替える感じで良いのでしょうか?

    実行してみたところ、Site speed inshightのスコアが劇的に上がりましたが、
    先述のプラグインのCSSが依然としてレンダリングをブロックしていると出ています。
    Site speed inshightは私の場合、スコアが劇的に上昇した直後に急降下することが多いため、
    質問させていただいています。

    ご迷惑にならなければご教授いただければ幸いです。
    宜しくお願い致します。

    • HTML やコードを WordPress のコメント欄にお書きになる際は、エンコードしないと削除されてしまいます。

      エンコードは、HTML特殊文字変換ツールで行えます。

      文章の途中が削除されていて詳細が分からないので、テスト環境で試しました。

      functions.php に、このコードを追加。

      add_action( 'wp_enqueue_scripts', function() {
        wp_dequeue_style( 'agp-core-repeater-css' );
        wp_dequeue_style( 'fac-css' );
      });

      <head> タグ内に、HTML を追加。

      <link rel="preload" href="/wp-content/plugins/agp-font-awesome-collection/assets/repeater/css/style.css" as="style" onload="this.onload=null;this.rel='stylesheet'">
      <noscript><link rel="stylesheet" href="/wp-content/plugins/agp-font-awesome-collection/assets/repeater/css/style.css"></noscript>
      <link rel="preload" href="/wp-content/plugins/agp-font-awesome-collection/assets/css/style.min.css" as="style" onload="this.onload=null;this.rel='stylesheet'">
      <noscript><link rel="stylesheet" href="/wp-content/plugins/agp-font-awesome-collection/assets/css/style.min.css"></noscript>
      <script>
      /*! loadCSS. [c]2017 Filament Group, Inc. MIT License */
      ここに縮小したcssrelpreload.jsを貼り付ける
      </script>

      これで 2 つのスタイルシートのレンダリングブロックは排除できるはずです。

      ただ、/wp-content/plugins/agp-font-awesome-collection/vendor/agp/agp-fontawesome/css/font-awesome.min.css のスタイルシートは、レンダリングをブロックします。

      このスタイルシートは @font-face で Font Awesome を読み込んでいるので、この記事の方法は使えません。Google フォントと同じく、as="font" での先読みが必要です。

      それと、Google フォントの読み込みでレイアウトが崩れる原因と思われるものは、以前のコメントに書いております。

  3. Akira様

    返信ありがとうございました。大変お手数かけてしまいました。
    Googleフォントの読み込みの際、レイアウト崩れを起こす件は、おっしゃられたように
    ;が抜けていたことでした。ありがとうございました。

    また、特殊文字コードの件、了承しました。コメントする際は今後気を付けます。

    Googleフォントの件は、前回のコメント欄の方に書かせていただきます。

    agp-font-awesome-collection/vendor/agp/agp-fontawesomeプラグインのCSSの件、コメント通りに試してみます。どうもありがとうございました。

送信に失敗しました

ボットと判定された可能性があります。

大変お手数をおかけしますが、以下の内容をご確認の上、再度のコメントの送信をお願い申し上げます。