この投稿では、googleスピードテストで100点を取るための方法を説明します。
1.ファイル(Files)
テーマやプラグインによってサイトに読み込まれているファイルをチェックする必要があります。そのためには、Googleスピードテストに移動し、サイトを確認してください。
「VIEW TREEMAP」ボタンをクリックします。ボタンをクリックすると、最も遅いファイルを見つけることができます。
私たちがよく目にするのは、アイコンフォントです。多くの開発者は、最適化されたカスタムアイコンフォントライブラリを作りたがらず、FontAwesomeライブラリをフルに使っています。
FontAwesomeアイコンはバージョンアップごとにどんどんサイズが大きくなっていきます。そこで、私たちは独自のアイコンフォントバンドルを作りました。その結果サイズは約1/5に縮小されました。
2.フォントとタイポグラフィ(Fonts and typography)
Webバイタルスコアが悪い2番目に多い理由です。多くのテーマが最低3つのカスタムフォントを使っています。これは多すぎます。私たちの場合はRobotoフォントを使いましたが、システムフォントの組み合わせで代替できることがわかりました。
以下はその例です。
body{font-family:Roboto,"Helvetica Neue",-apple-system,system-ui,BlinkMacSystemFont,"Segoe UI",Oxygen-Sans,sans-serif;}
外部Robotoフォントの代わりにこのフォールバックフォントを使用することで、100kb近くを節約することができ、外部からのリクエストも1回で済みます。
※最も人気のあるページビルダーであるElementorでも、外部Robotoフォントが使用されていることがわかりました。グローバルフォントオプションを開き、すべてのグローバルフォントオプションでRobotoフォントを無効にします。
3.CSSフレームワーク(CSS framework)
ほとんどのテーマはBootstrap、Materialise、Foundaryやその他のフレームワークを使用しています。確かにフレームワークには便利なスタイルがすべて備わっており、新しいブロックのために何度も新しいスタイルを作る必要がないため、理にかなってはいます。しかし、これには代償があります。Bootstrapは基本的なスタイルで最低200kbあります。カスタマイズされたBootstrapを使用することも考えましたが、すべてのスタイルを一緒に追加するのではなく、現在必要なスタイルだけを追加しました。
例 – Bootstrapには、モバイルのマージンをコントロールするためのスタイルがたくさんあります。例えば、モバイルだけ10pxの右マージンを追加したり、タブレットだけ10pxの右マージンを追加することができます。しかし、そのようなスタイルが使われることはありません。99.99%の場合、モバイルサイトを構築するときは、すべての要素を下に積み重ねて、下部にのみ余白を持たせます。そこで、私たちは、モバイルの下部マージンのみにスタイルを追加しました。
その結果、一般的なスタイルのフレームワークが200kbから20kbになりました。同時に、フレックスボックスや他の一般的なシステムの使用に制限されることもなく、Bootstrapや他のフレームワークのアップデートを待つことなく、CSSグリッドや他の実験的な機能も使用することができます。
.grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
grid-gap: 10px;
}
このコードは、”grid “コンテナのすべての内部ブロックを取り込み、隙間のあるカラムとして配置し、レスポンシブ・スタイルで、ブロックの幅に自動フィットさせます。
これは単なる例であり、次の動画でもcssによる最新の1行ソリューションを見つけることができます。
4.条件付きアセットローディング(Conditional asset loading)
99%の開発者はこのことを気にしていないように感じます。条件付きアセットローディングとは何かを説明します。
テーマやプラグインに特別なブロックがあるとします。ほとんどの開発者はこのブロックのためにスタイルとスクリプトを作成し、プラグインがインストールされたときにそれらを直接読み込みます。これは大きな間違いです。開発者は、すべてを論理的なブロックに分割し、このブロックごとにファイルを作成する必要があります。
以前、Webバイタルが要求される前、googleやgtmetrixは、ブラウザからファイルへのリクエストが多いとスコアを減らしていました。すべての開発者は、すべてのスクリプトとファイルを1つのファイルに追加しようとしました。しかし現在は違います。googleは、リクエスト数を減らす代わりに、ファイルサイズを小さくすることを望んでいます。そこで、私たちはすべてのスクリプトとスタイルを論理的なパーツで分割し、別々のファイルにしました。たとえ数行のコードであっても。すべてのブロック、ウィジェット、モジュール、ショートコード、Gutenbergブロックのスタイルとスクリプトを別々に作成し、ページ上でブロックが使用されている場合のみ有効にしました。その結果120kbを節約できました。
ここで、一つの大きな問題について議論する必要があります。条件付きアセットローディングをどうするか?という問題です。
WordPressには、スタイルやスクリプトを読み込んだり登録したりするための関数がいくつか用意されています(wp_enqueue…)。条件付きアセットローディングについては、wp_add_inline_script関数とwp_add_inline_css関数があります。これらはとても便利ですが、他のファイルに割り当てる必要があります。つまり、単体のレンダー関数としては使えないということです。
テンプレートパーツでwp_enqueue_styleを使用すると、事態はさらに悪化します。問題はテンプレートでスタイルファイルをリクエストした場合に、WordPressがスタイルファイルを読み込む場所にあります。フッターで読み込まれWebバイタルに巨大なCLS(レイアウト・シフティング・エラー)を発生させます。そこで、スタイルの不具合やずれを防ぐために、レンダー・ブロッキングを行わず、コンテンツの前にスタイルを条件付きで読み込む必要があります。
残念ながら、WordPressのコアにはこのような機能はありません。私たちは独自の関数をいくつか作り、さまざまな場所で適切に使用しています。以下はそのロジックです。
インラインスタイル:Inline styles
多くの方がインラインスタイルは使うべきではないと書いているが、私たちはそうは思いません。インラインスタイルは非常に高速で、コードが多すぎない場合には最適な方法です。特に簡単なカスタマイズのためのオプションがあれば便利です。次のようなコードを使えば問題ありません。
<div style="background:red">Red bg</div>
インラインスコープ:Inline scope
ここでもインラインスタイルを使用しますが、別のブロックとして使用します。
<div class="red"><style scoped>.red{background:red}</style>My red block</div>
ベストな解決策ではないかもしれませんが、特別なブロックのためだけに使用する必要がある数行のコードがある場合、私たちはこのオプションを使用します。条件付きスタイルを追加することができ、CLSやキャッシュプラグインとの非互換性を防ぐことができます。私はこのオプションをあまり使わないようにしていますが、グローバル部分とは異なるカスタムスタイルを持つカスタムテンプレート部分を作る必要がある場合は、このオプションが最適であることがわかりました。
トランジェントを使ったコンディションの保存:Using transients to store conditions
これは、条件付き読み込みのためのよりエレガントなソリューションです。例えば、ポストグリッドをレンダリングするテンプレート部分があるとします。しかし、このブロックのスタイルを共通スタイルに追加したくありません。もしかしたら、ユーザーはグリッドではなくリストを表示したいかもしれません。
そこで、トランジェントを作成します。これを「conditional_asset」と呼ぶことにします。
テンプレート・パートで、このconditional_assetトランジェントを取得し、ブロック名を追加します。
次に、wp_headフックでこのトランジェントをチェックし、その中にブロック名があれば、ヘッダーにスタイルをレンダリングします。トランジェント・キャッシュを1日に設定すれば、このブロックをページから削除しても、トランジェントは削除され、再保存されないので、スタイルは読み込まれません。
ローディングのための名前によるチェック:Checking by name for loading
私たちがよく使う素晴らしいハックを紹介します。コンテンツブロック(gutenberg、ショートコード、ページビルダーブロックなど)がコンテンツに保存されている場合、stripos php関数で簡単に確認できます。
global $post;
$postcontent = $post->post_content;
if(stripos($post_content, 'boxnumber') === 0){
echo '';
}
このコードでは、ページに「boxnumber」というクラス、id、単語を持つブロックがあるかどうかをチェックし、もしOKなら、条件付きスタイルを読み込むことができます。
5.画像読み込み(Image loading)
これはWordPressの最も弱い部分です。WordPressには優れたリサイザー機能がありません。そのため、テーマやプラグインの開発者としては、ほとんど選択肢がありません:
- 独自のカスタムリサイザーを使用することができます(ただし、CDNやキャッシュプラグインの種類によって問題が発生します)。
- 画像のカスタムサイズ add_image_size を登録することができますが、これはアップロードされたすべての画像のコピーを、ページで使用していなくても、別に生成します。
- 画像の遅延ロードをカスタムできます。
私たちは最終的にハイブリッド方式を採用することにしました。小さな画像や、クライアントのサイトであまり使用されないブロックについては、独自のリサイザーを使用しました。CDNやプラグインとの互換性がないとしても、クライアントがカスタムCDNのあるサイトでこのブロックを使う可能性はほとんどありませんし、問題があれば別のウィジェットやブロックを使うこともできます。
ほとんどの一般的なブロックと商品ループのために、私たちは画像のいくつかの事前定義されたサイズを作成し、私たちは画像のためのカスタム遅延ロード、画像のためのカスタムフォールバック、Ajaxされた部分のサポートを追加することを可能にする通常のWordPress関数の周りに特別なラッパーを追加しました。
WordPress 5.5以降では内部画像の遅延読み込みができるようになりました。
これは、画像サイズに関するさまざまな種類のgoogleの警告に関する問題を修正したものです。しかし、最初の画面で画像を使用する場合、googleは最初の画面でページをチェックする前にすべてのスクリプトを実行します。つまり、ページ上部に横幅いっぱいの大きな画像を表示させると、LCPが大きくなりすぎてしまい、ほとんど対応できないのです。
ですからたとえ遅延ロードがあったとしても、最初の画面では大きな画像を使わないことをお勧めします。この目的のために、私たちは小さなフィーチャー画像を表示する多くの記事レイアウトを作りました。また、フィーチャー画像を全く表示せず、なおかつ見栄えのする特別なレイアウトも作りました。
6.ユーザー操作によるスクリプトのロード(Loading scripts on user interaction)
私たちは、あるブロックが他のブロックよりもスピードに大きな影響を与えることを発見しました。例えば、サードパーティのライブラリを使ったブロックは、サイトの速度を大幅に低下させます。特に、このブロックがページ上で重要な値を持っていない場合は問題です。例えば、自動再生されるビデオ、Lottieファイル、3Dオブジェクトなどです。そこで、私たちはjavascriptで、ユーザーとのインタラクションにのみスクリプトをロードできる特別なオプションを見つけました。
ユーザーがページを開いたとき、このブロックは隠れていて、スクリプトは読み込まれません。しかし、ユーザーがスクロールを始めると、バックグラウンドでスクリプトが読み込まれます。ユーザーがこのブロックに到達すると、スクリプトは完全にロードされ、利用可能になります。
これはJavascriptのこのような関数の例です。
const body = document.body;
var loadedtdel = false;
const onInteraction = () => {
if (loadedtdel === true) {
return;
}
loadedtdel = true;
const modelViewerScript = document.createElement("script");
modelViewerScript.type = "module";
modelViewerScript.src = "https://site.com/js/js/model-viewer.min.js";
body.appendChild(modelViewerScript);
};
body.addEventListener("mouseover", onInteraction, {once:true});
body.addEventListener("touchmove", onInteraction, {once:true});
body.addEventListener("scroll", onInteraction, {once:true});
body.addEventListener("keydown", onInteraction, {once:true});
ここでは、スクリプトmodel-viewer.min.jsを、スクロール時、タッチ時、キー押下時にのみ読み込むようにしています。
7.アニメーションの最適化(Optimization for animations)
ほとんどの開発者は、CSSアニメーション・ライブラリを使ったり、独自のCSSアニメーションを作ったりしています。確かに、使いやすいので開発には向いています。しかし、追加のスタイル(通常50-150kb)を読み込む必要があるため、スピードの面では良くありません。私たちは代わりにGSAPを使いました。GSAPは最も最適化されたアニメーションJavaScriptライブラリです。いくつかのシナリオでは、CSS変換よりもさらに速く、非常に強力です。私たちはWOWアニメーションフレームワークを追加し、レンダリングブロックがなく、非常にスムーズな多くの強力なアニメーションをデモで見ることができます。
もし、いくつかのアニメーションが必要なだけであれば、cssでも問題ありませんが、多くの異なるマイクロアニメーションで複雑なテーマを作成する場合は、GSAP、Anime.jsまたは他のjavascriptライブラリを使用してみてください。
8.キャッシュ・プラグイン(Cache plugins)
最後に合理的で良い設定のキャッシュシステムがなければ、100点を獲得することは不可能です。このことをご理解いただければ幸いです。
まとめ
これらが私たちがテーマとプラグインでWebバイタルを改善するために使用した方法です。しかし、テーマとプラグインはスピードスコアの30-50%に過ぎません。残りの50%はホスティングとキャッシュの最適化です。ホスティングでチェックする必要があるのはTTFBです。100ms以上であれば、ホスティングを変更するか、Cloudflareを追加したほうがよいでしょう。例えば、利用中のサーバーが日本にある場合、ヨーロッパからのユーザーはTTFB(Time To First Byte)が大きすぎることになります。あなたのサイトが日本向けであれば問題ありませんが、世界中のユーザー向けであれば大きな問題となります。以上、皆様のサイトWebバイタル向上に役立てれば幸いです。最後までご覧いただきありがとうございました。