サイトアイコン Capital P

【WV.7】サードパーティーリソースの削減または改善

Core Web Vitalに関する連載の7回目は、サードパーティーリソースを減らす方法について説明する。FCPおよびFIDに関する項目で、改善することでユーザーが利用できるようになるまでの速度向上を見込める。

第三者コードは基本的に悪影響が多い。

サードパーティーリソースというのは、WordPressで読み込まれるJavaScriptおよびCSSのうち、SNSやWebサービスのSDKなど、解析ツールのJSなど、別ドメインから読み込まれるものである。こうしたリソースは基本的に「あらゆるユースケースを想定した全部入り」であることが多く、Core Web Vitalの基本原理「必要最低限の読み込み」と背反している。

本稿ではこれらの削減方法と、どうしても削減できない場合の次善策および割り切りについて説明する。

ステップ1. 不要なサードパーティーの検証

Page Speed Insightsで指摘されるサードパーティーには、たとえばFacebook JS SDKがある。これは「公式いいねボタン」を表示するときに読み込むよう指定されるもので、シェアボタン系のプラグインなどを通じて読み込まれる。

これが公式の提示するコード。

しかし、Facebook JS SDKは「Facebookの提供する機能を外部サイトから利用するときのほぼすべて」がつまったJavaScriptであるため、defer/async による遅延読み込みをしたところでその大半は使われることがない。なんといっても、我々がWebサイトに「いいね!」ボタンを表示したいのは、「このページがいかに価値があるか」を人数によってマウンティングしたいから、というそれだけの理由なのである。

1,164人が「いいね!」しました。この言葉が聞きたかった。

はたして、ユーザーにとって価値があるのかどうかわからない数字のために、この長大なライブラリを読み込むべきだろうか? ほんとうに「いいね!」してほしいのか? Facebook上で「いいね!」されたコンテンツは本当に優遇されているのか? 広告なしで? 20ドル追加でもっと多くの人に読まれますっていいたいだけじゃないのか? sharer.php にアクセスしてシェアして貰えばよくないか?

と、いくつかの要素を検討した結果、JSで「いいね!」ボタンを諦め、通常のリンクによるシェアボタンに切り替えたとしよう。これはこれで悪くない決断である。実際、こうした需要に応えるためのプラグインも存在するし、Jetpackのシェアボタンにも公式ボタン以外のオプションは存在する。

JetPackの共有ボタン設定。公式ボタン以外はJSが使われない。

もちろん、Facebook JS SDKの優れた機能に依存したサイトであれば、なくすことはできないので、そこらへんはトレードオフだ。不要だと割り切ることができるのであれば、ないにこしたことはない。

ステップ2. よりよいオプションがないか検討する

サードパーティーリソースを提供する側で高速化の需要に対応しているケースがいくつかある。正しく設定されているか確認し、もしプラグインなどを経由して読み込まれているのであれば、可能な限り修正しよう。

例1. Google フォント

日本語はアルファベットからなら西欧諸語と異なり、文字数が異常に多い。Webフォントを使う場合はファイルサイズとして反映される。Googleフォントではこの問題にすでに対応しており、ベストプラクティスも提供されている。たとえばNoto Sans JPの400(regular)と700(Bold)を読み込むコードとして提供されるのは次の通り。

<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Noto+Sans+JP:wght@400;700&display=swap" rel="stylesheet">
  1. CSSはユニコードレンジに分割されているので、フォント全体がダウンロードされるわけではない。
  2. 複数のフォントファミリーでも一つのリクエストにまとめられる。
  3. ウェイトを指定すれば容量削減。指定しないと使用しないウェイトが100〜900まで読み込まれてしまう。
  4. 勝手につく display=swap はWebフォントの読み込みにおける推奨プロパティ font-display: swap に対応する。
  5. preconnectによるDNSルックアップの最適化もついている。

上記をWordPressに組み込むなら、次のようになる。

// preconnect を出力
add_action( 'wp_head', function() {
    echo <<<HTML
        <link rel="preconnect" href="https://fonts.googleapis.com">
        <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
HTML;
} );

// スタイルシートを読み込み
add_action( 'wp_enqueue_scripts', function() {
     wp_enqueue_style( 'noto-sans-jp', 'https://fonts.googleapis.com/css2?family=Noto+Sans+JP:wght@400;700&display=swap', [], null );
} );

さて、コアのコードを確認してみると、どうもエディター用のフォントCSS wp-editor-font古いAPIのURLを参照しているようだ。font-displayの指定も付いていない。5.7からは使われなくなっているようなので、このままでもよいのだが、もし修正するなら次の通り。プラグイン・テーマがこのCSSに依存している場合は有効になる。

/**
 * gettextで指定されるエディターのフォントを変える
 *
 */
add_filter( 'gettext_with_context', function( $translation, $text, $context ) {
	switch ( $context ) {
		case 'CSS Font Family for Editor Font':
			$translation = 'Noto Sans JP';
			break;
	}
	return $translation;
}, 10, 3 );


/**
 * フォントCSSのURLを変更
 */
add_filter( 'style_loader_src', function( $src, $handle ) {
    if ( 'wp-editor-font' === $handle ) {
        $src = 'https://fonts.googleapis.com/css2?family=Noto+Sans+JP:wght@400;700&display=swap';
    }
    return $src;
}, 10, 2 );

例2. FontAwesome

FontAwesomeは有名なアイコンライブラリだが、アイコンフォントとSVGの両方の読み込みを提供している。

FontAwesomeのコード取得画面

アイコンフォントはCSSの中に利用されるすべてのアイコンが記載されるのでパフォーマンスが悪い。必要なアイコンだけが読み込まれるSVG版を利用しよう。通常のWebサイトは1つのページに100個もアイコンを表示しない。

もしブロックエディターでアイコンを利用しているのであれば、エディターではアイコンフォント+CSS、公開画面ではSVGとわけるようにしよう。エディターでは利用するアイコンは未確定だが、記事を公開してしまえばもう変わることはないからだ。

ちなみに、こうしたアイコンに関してはSVG Spriteという手法が最近は流行りのようで、Bootstrap Iconsなどはこの手法に対応している。

<svg class="bi" width="32" height="32" fill="currentColor">
  <use xlink:href="bootstrap-icons.svg#heart-fill"/>
</svg>

SVGは「背景画像にするかSVGタグで埋め込み」という手法を取らないとCSSで色を変更することができないため、慣れ親しんだWebフォントで利用したくなってしまうが、SVGの方がパフォーマンスに優れることを覚えておこう。SVGならブラウザキャッシュも効くので、複数ページに渡って閲覧されるような場合はよい効果が見込める。

例3. Jetpack

Jetpackはサードパーティーリソースではないが、ついでに紹介しよう。Jetpackがデフォルトで読み込むCSSはとにかくでかい。これは分割することができるので、可能なら分割しよう。

// JetpackのCSS結合を停止
add_filter( 'jetpack_implode_frontend_css', '__return_false' );

これで分割完了だ。ホスティングがHTTP/2 に対応していれば分割されていても大抵の場合は問題ないので、こちらの方がよいだろう。CSS/JS結合は2010年以前に読み込みスピードアップのために導入されたテクノロジーだが、最近はあまり流行っていない。

ステップ3. あきらめる

いろいろと検証した結果、どうしても削減できないケースもあり得る。

たとえばメディアサイトにおける広告コードなどはどうしても削減できないものの一つだろう。一般的に広告の入ったページでは Page Speed Insights の点数は高くならない。コードの発行側(=広告主・代理店)にとってはサイトの中で早く動く方がメリットが大きいので、メインスレッドの先頭で複雑な処理をおこないがちだからだ。かといって、「じゃあ明日から広告全部消しますね」とはならないだろう。

どうしても削除できないリソースの場合でもいくつかできることはあるのでやっておこう。

まとめ

以上、サードパーティーリソースの読み込みに関する削減および改善方法を紹介した。

  1. なくせるならなくす
  2. よりよい読み込み方法が提供されているならそちらを使う
  3. なくせないならせめてもの改善を試みる
モバイルバージョンを終了