先日公開した新しい自作テーマがとうとうPageSpeed Insightsのスコア100点をとることが出来ました!
実際100点を取ってみると「PageSpeed Insightsで100点とったところで誰も幸せにならない」という悲しい結果に至ったのですが…
それでも、PageSpeed Insights 100点をとるためにやってきた「Webサイト表示高速化の為のいろいろな施策」はたくさんの勉強とアイデア・試行錯誤を詰め込んだひとつの成果物だと思います。
今回は僕が今までやってきた「WordPressサイト高速化の施策」について紹介致します!
目次
WordPressサイトの表示高速化とPageSpeed Insights 100点という目標
自称PageSpeed Insights 100点マン。よっひー(@yosiakatsuki)です。
僕はこれまで「サイトの表示はとにかく速いほうがいいに決まっている」という謎の信念の元、WordPressサイトの表示高速化に取り組んできました。
「Webサイト高速化」と聞くと、指標としてよくあげられるGoogleの「PageSpeed Insights」のスコアです
PageSpeed Insightsのスコアが高いほどGoogleの検索結果に有利らしいので「サイトを運営する上で、必要な機能をある程度を残しつつPageSpeed Insightsで100点をとる」ということを目指して調整を続けてきたのですが…
最終的に「PageSpeed Insightsのスコアが100点」なら「ページの表示速度が超高速」とは限らないという結論に至りました。
とはいえ、PageSpeed Insightsでの提案に素直に対処していくことはWebサイトの表示高速化に繋がることは確かです
今回は「サイト高速化の為にやったこと」と「PageSpeed Insightsで100点をとるためにやったこと」の2つの軸でWebサイト高速化の為に試行錯誤してきたことをご紹介します
※基本的にWordPressで運営しているサイトでの改善方法になりますが、WordPress以外でも参考になる箇所もあると思います。ご参考にしていただけますと幸いです。
Webサイト表示高速化の為にやったこと
『「PageSpeed Insightsのスコアが100点 = サイトの表示速度が爆速」とは限らない』
と、いきなりわけわからない事を言いましたが、PageSpeed Insightsの提案に素直に従うことはWebサイト高速化への本質的な対応になるのではないかと思います。
まずは、PageSpeed Insightsの10個の提案にどのように対応していったかお話します
- CSS を縮小する
- HTML を縮小する
- JavaScript を縮小する
- サーバーの応答時間を短縮する
- スクロールせずに見えるコンテンツのレンダリングをブロックしている JavaScript/CSS を排除する
- ブラウザのキャッシュを活用する
- リンク先ページのリダイレクトを使用しない
- 圧縮を有効にする
- 画像を最適化する
- 表示可能コンテンツの優先順位を決定する
CSS, HTML, JavaScriptの縮小
まず簡単に出来そうなことは、CSS、JavaScriptの縮小です。
CSS,JavaScript内の改行や余分なスペースを削除し、ファイルサイズを圧縮します。
WEB上からファイルをダウンロードする際、ファイルサイズの小さいもののほうが早くダウンロード出来る…と同じ原理です。
CSS,JavaScript縮小については次のようなWEBサービスがとても便利です。
HTMLの縮小についてはWordPressプラグイン等で出来るようですが、「表示がおかしくなった」等の声も聞いたことがあるので、おすすめはできません…
ちなみに当ブログではHTMLの縮小に関しては何も対策していませんが、PageSpeed Insightsで問題点として挙げられていないので、よっぽど改行とスペースが多くなければ問題ないと思います。
サーバーの応答時間を短縮する
「サーバーの応答時間を短縮する」については、
- メモリ・CPUの潤沢なサーバーを利用する
- OPcacheなどのキャッシュ機能を利用する
- プログラムから冗長な処理を排除する
…などがあるでしょうか。
WordPressであれば余分な処理をさせないために「使っていない・実は必要ないプラグインを停止する」ということも重要でしょう。
僕はいくつもプラグインをインストールしていますが、表示に関わる操作をするプラグインは極力使わず、管理を楽にするためにプラグインを使っています。
テーマのカスタマイズをする際は「ループを多用しない」ということも気をつけていて、関連記事一覧など動的に出力する部分は最小限に抑えるようにしています。
レンタルサーバーを契約してブログを運営している場合は、レンタルサーバーで提供している高速化の仕組みを利用しておけばひとまずOKだと思います。
当ブログもお世話になっているエックスサーバーでは「FastCGI」「APC/OPcache」といったPHPの動作高速化設定が可能です。
僕としては、サイトの表示速度はサーバー側よりフロントエンド側のほうが影響が大きいので、サーバーサイドでの調整は「ほどほど」で十分だと思います。
スクロールせずに見えるコンテンツのレンダリングをブロックしている JavaScript/CSS を排除する
僕はこの項目が一番ハードルが高いのではないかと思います
この項目、ざっくり言うと「ファーストビュー部分はcssもJavaScriptも外部読み込み無しで表示させなさい」ということになります。
具体的には…
- JavaScriptのインライン化
- cssはファーストビュー部分だけインライン化・それ以外はページが読み込まれた後でcssファイルを読み込む
…といった対応が必要になります。
具体的な修正方法はGoogleのドキュメントに書かれています
実際にテーマを修正していく場合、JavaScriptの部分であれば、インラインでJavaScriptの処理を書いたり、</body>
の直前にasync
属性付きでscript
タグを書いていきます。
<!-- ** 例 ** -->
<script async type="text/javascript" src="<?php echo get_template_directory_uri(); ?>/js/sample.js"></script>
</body>
cssについては「ファーストビューに関係する部分のスタイル」をインライン化し、それ以外を遅延読み込みさせます。
問題は「ファーストビューに関係する部分ってどこまでのことだ??」ということですが…
基本的にはPC・スマホとも、スクロールせずに見えている部分全てが対象になります。
インラインで書くべきスタイルの一例としては…
- リセットcss
- ヘッダー部分のスタイル
- コンテンツ域の最大幅や2カラム表示にさせるためのスタイル
- 記事タイトル部分
- アイキャッチ画像部分
…など、、
サイトによって書くべき部分が異なり、かなりの応用問題となります
ちなみにFont Awesomeなどのアイコンフォントをファーストビューで表示させようとするとこの項目で怒られます。
もしそういった場合はファーストビューではアイコンフォントを使わないか、SVGの利用を検討してみて下さい。
以上のことから、「人に教えられるほど」ではなくていいですが、cssとhtmlを多少なりとも自分で書けないと対応は難しいと思います…
ハードルはかなり高めです…
自分でできなければ、焼き肉でもおごって出来る人に手伝ってもらったほうが早いかもしれません。
ブラウザのキャッシュを活用する
画像やcss,JavaScriptなどのリソースをブラウザでキャッシュできるように設定します。
大体のレンタルサーバーでは.htaccess
ファイルに追記することでキャッシュを有効にしたり、時間の変更が可能です。
当ブログでは以下のような設定を書いています
<IfModule mod_expires.c>
ExpiresActive On
# キャッシュ初期化(1秒に設定)
ExpiresDefault "access plus 1 seconds"
# MIME Type ごとの設定
ExpiresByType text/css "access plus 1 year"
ExpiresByType text/js "access plus 1 year"
ExpiresByType text/javascript "access plus 1 year"
ExpiresByType image/gif "access plus 1 year"
ExpiresByType image/jpeg "access plus 1 year"
ExpiresByType image/png "access plus 1 year"
ExpiresByType image/svg+xml "access plus 1 year"
ExpiresByType application/javascript "access plus 1 year"
ExpiresByType application/x-javascript "access plus 1 year"
ExpiresByType application/x-font-ttf "access plus 1 year"
ExpiresByType application/x-font-woff "access plus 1 year"
ExpiresByType application/x-font-woff2 "access plus 1 year"
ExpiresByType application/x-font-opentype "access plus 1 year"
ExpiresByType application/vnd.ms-fontobject "access plus 1 year"
</IfModule>
とりあえずデフォルトは1秒で画像やcss、JavaScript、アイコンフォントなどは1年にしました。
これはサーバー側が対応していれば書き足すだけで効果があるのでぜひやっておきたい項目です。
.htaccessの編集の為にはFTPソフトを使ってファイルをダウンロードする必要があるかと思いますが、レンタルサーバーによってはレンタルサーバーの管理画面から.htaccessファイルを編集出来るかもしれません!
(エックスサーバーは管理画面から.htaccessを編集する事ができます)
リンク先ページのリダイレクトを使用しない
PCとスマホでURLを変えていたり、その他リダイレクトの設定をしていなければ特に問題ないと思われる項目です。
当ブログでは何も対策していません!
圧縮を有効にする
こちらもブラウザキャッシュ同様、.htaccessに追記をするだけで効果ありな項目です!
当ブログでの設定はこちら↓
# gzip圧縮の設定
<IfModule mod_deflate.c>
SetOutputFilter DEFLATE
# 古いブラウザでは無効
BrowserMatch ^Mozilla/4\.0[678] no-gzip
BrowserMatch ^Mozilla/4 gzip-only-text/html
BrowserMatch \bMSIE\s(7|8) !no-gzip !gzip-only-text/html
# 画像など圧縮済みのコンテンツは再圧縮しない
SetEnvIfNoCase Request_URI \.(?:gif|jpe?g|png|ico|eot|woff|woff2)$ no-gzip dont-vary
AddOutputFilterByType DEFLATE text/plain
AddOutputFilterByType DEFLATE text/html
AddOutputFilterByType DEFLATE text/xml
AddOutputFilterByType DEFLATE text/css
AddOutputFilterByType DEFLATE text/js
AddOutputFilterByType DEFLATE image/svg+xml
AddOutputFilterByType DEFLATE application/xml
AddOutputFilterByType DEFLATE application/xhtml+xml
AddOutputFilterByType DEFLATE application/rss+xml
AddOutputFilterByType DEFLATE application/atom_xml
AddOutputFilterByType DEFLATE application/javascript
AddOutputFilterByType DEFLATE application/x-javascript
AddOutputFilterByType DEFLATE application/x-httpd-php
AddOutputFilterByType DEFLATE application/x-font-ttf
AddOutputFilterByType DEFLATE application/x-font-opentype
</IfModule>
この設定はいろんなサイトを参考にしながら足したり引いたりして出来上がってます。
画像を最適化する
サイトで表示させる画像はTinyPNGやJPEGminiなどのツールを使って画像を圧縮します
毎回圧縮するのが面倒ならEWWW Image OptimizerというWordPressプラグインを導入することでメディアライブラリに画像をアップロードする際に自動で圧縮することも出来ます。
ツールを使った圧縮処理をしてもまだ指摘が消えない場合は、アップロードした画像の大きさ(容量ではなく、縦横の長さ)を確認してみて下さい。
必要以上に大きい画像を使っている場合は適切なサイズにリサイズすることで指摘が消えるかもしれません。
ちなみに当ブログでは画像の圧縮は「Compress JPEG & PNG images」というプラグインを使っています。
表示可能コンテンツの優先順位を決定する
「スクロールせずに見えるコンテンツのレンダリングをブロックしている JavaScript/CSS を排除する」の項目がクリアできれば問題ありませんが、もしCSSやJavaScriptを複数読み込んでいる場合、読み込み順序を調整してあげる必要があります。
とにかく、ファーストビューに関連するリソースを先に読み込ませるように順序を調整します。
PageSpeed Insightsの提案まとめ
恐らく最後まで戦うことになるのは「スクロールせずに見えるコンテンツのレンダリングをブロックしている JavaScript/CSS を排除する」と「画像を最適化する」だと思います。
逆を言えばその他の項目は比較的対処しやすい部分でもあるので、時間を作って対処してみて下さい。
ここから先はPageSpeed Insightsの提案以外でWEBサイト高速化の為にやったことです。
画像を非同期読み込みさせる「Lazy Load」
「Lazy Load」(レイジーロード)は画像を遅れて読み込ませる仕組みのことです。
ページを読み込んだタイミングではすごく軽いダミー画像を読み込ませることで表示速度を高速化し、画像が表示されるであろう位置までスクロールしたタイミングで本当に表示したい画像を読み込ませる…といった仕組みです。
例えばページ表示したタイミングで100MB分の画像を一気に読み込むよりは、必要なタイミングで1MBずつ分割して100枚の画像を読み込んでいったほうがユーザーにとっては画像を読み込むまでの待ち時間を短く感じることができます。(100MBは極端ですが…)
ただ、画像の読み込みタイミングの設定によっては画像がスクロールより後に表示されてしまい、かえって「うっとおしい」と思われる恐れもあるので、注意が必要です。
画像の読み込みタイミングを十分早めに設定しておくことでスクロールした時にはもう画像が表示されている…という状況を作ることは可能ですのでうまく調整が必要です。
JavaScriptの遅延ロード
「Lazy Load」からヒントを得て、「どうせならJavaScriptもある程度スクロールしてから読み込ませてしまえばいいのでは?」ということで、当ブログでは次の例のようなJavaScriptを書いています。
//-----------------------------------------------
//スクロール量取得
//-----------------------------------------------
function ys_get_scroll(d) {
return d.documentElement.scrollTop || d.body.scrollTop;
};
//-----------------------------------------------
//スクリプト読み込み
//-----------------------------------------------
function ys_script_load(d, id, src) {
var js;
if (!d.getElementById(id)) {
js = d.createElement('script');
js.id = id;
js.src = src;
js.async = true;
d.body.appendChild(js);
}
};
//-----------------------------------------------
//スクロール時に実行する処理
//-----------------------------------------------
function ys_scroll_main() {
d = document;
// スクロール量がヘッダー高さ未満ならreturn
if(d.getElementById('masthead').offsetHeight > ys_get_scroll(d)){
return;
}
// twitter
ys_script_load(d,'twitter-wjs','//platform.twitter.com/widgets.js');
//…などなど
};
//スクロール時のイベント設定
window.addEventListener( "scroll", ys_scroll_main);
SNS関連のボタン表示や埋め込み表示のために必要なJavaScriptはページ読み込み時ではなく、少しスクロールをしたタイミングで読み込ませています。
実際は複数スクリプトを一気に読み込んでブラウザがカクついてしまうのを抑える処理が入っているのですが、考え方的には上記コードそのままです。
「Webサイト表示高速化の為にやったこと」まとめ
PageSpeed Insightsの提案のみ素直に対応していくのも大事ですが、僕が自分のブログの表示高速化でこだわり続けてきたのは…
「ページの初期表示だけはとにかく早く!それ以外は遅れて読み込ませればいい!」
…ということです!
最初にページを表示した時に見えない部分って別に読み込んでくれなくてもページを見てる方は問題ないじゃないですか。
そんなことより、ブラウザに表示されるページ読み込み中を表すクルクルや左から右に伸びるインジケータをいち早く消し「さぁ!読み進めて下さい!」という状態にすることが重要ではないのかな…?
というのが僕のWEBサイト高速化へのこだわり、持論なのでした。
PageSpeed Insightsで100点をとるためにやったこと
前述の「Webサイト表示高速化の為にやったこと」でPageSpeed Insightsの提案に対して全て対処しきればスコア100点になっているはずです。
なのですが、どうしても運営上100点にできない理由があります。
Google AnalyticsとGoogle Adsenseです
運営内容によっては他の理由もあるかもしれませんが、ブログ運営している方はこの点がネックになることが多いと思います。
どちらもJavaScriptを遅延読み込みさせることで対応可能ではありますが、Google Analyticsのトラッキングコードを遅延読み込みさせたら正しいアクセス数が記録できるか怪しいですよね…
Google AnalyticsとGoogle Adsenseを残してもスコアは90点以上にはなると思うので、十分だと思いますが「どうしても100点取りたい!」という場合は下記の関数(PHP)を使ってみて下さい。
function ys_is_pagespeedinsights() {
$bot_list = array( 'Google Page Speed Insights' );
$is_bot = false;
foreach ( $bot_list as $bot ) {
if ( false !== stripos( $_SERVER['HTTP_USER_AGENT'], $bot ) ) {
$is_bot = true;
break;
}
}
return $is_bot;
}
使い方の例はこちら↓
if( ! ys_is_pagespeedinsights() ){
//Page Speed Insightsでは消したい項目
//Google Analyticsのトラッキングコード、広告、などなど…
}
…のように、要はPageSpeed Insightsで表示されては困るものをひたすらサーバーサイドの処理で削っていくということをすれば簡単に100点取れてしまいます。
度が過ぎる出し分けをすると、Googleが他に巡回させているbotでの読み込み内容と違うということでスパム扱される可能性もある…かもしれませんので、もし同じことをやる場合は自己責任でお願いします。
まとめ
「PageSpeed Insightsで100点とる」ことを目的にせず、「ユーザーがストレス無く閲覧できるサイト」を目的にWEBサイト高速化に引き続き取り組んでいきたいと思います。
(…今となってはサイト高速化よりAMP対応の方が優先度高めだと思いますが…これまた敷居が高い…)
ではまた。