こんにちは。デザイン部でフロントエンドエンジニアをしているkitoです。今回は、Webサイトの高速化を行う際にひとつの基準になりえるPageSpeed Insights について、主にフロントエンドで行える具体的な施策とともにご紹介したいと思います。
PageSpeed Insightsとは?
PageSpeed Insightsは、Googleが提供しているWebサイトのパフォーマンスをスコア化して具体的な改善案を提案してくれるサービスです。スコアの範囲は0~100ポイントで、85ポイント以上が良好とされています。85ポイント以上のスコアであったとしてもPageSpeed Insightsは継続的に改良されているので、定期的にチェックすることをお勧めします。試しにhttps://developers.google.com/speed/pagespeed/insights/に行き、任意のサイトのURLを入力してパフォーマンスを計測してみてください。何の対策もされていないサイトであればスコアが85以下で、ステータスが「Poor」か「Needs Work」になっているかと思います。このスコアは、体感的なサイトパフォーマンスとは必ずしも一致しませんが、PageSpeed Insightsで提案される改善案は具体的で取り組みやすく、筋が良いものが多いのでスコア改善に取り組む価値はあると思います。
スコア下に「適用可能な最適化」という具体策が下記のように列記されているはずです。(対応済み項目は下部にある「適用済みの最適化」に表示されます)
- 画像を最適化する
- ブラウザのキャッシュを活用する
- スクロールせずに見えるコンテンツのレンダリングをブロックしている JavaScript/CSS を排除する
- 表示可能コンテンツの優先順位を決定する
- 圧縮を有効にする
- JavaScript を縮小する
各項目にある「修正方法を表示」をクリックするとプルダウンで、修正すべきコンテンツが表示されます。
例えば、「画像を最適化する」だと圧縮すべき画像の一覧が「〜.jpg を圧縮すると 154.4 KB(71%)削減できます。」という形で表示されるので具体的なアクションが取りやすいです。
私が開発・運営に関わっているサイトでは、対策以前はモバイル・パソコンのスコアはそれぞれ60前後でしたがPageSpeed Insightsに提案された対策を可能な範囲で行うことで、85~90以上のスコア「Good」で安定するようになりました。
では具体的に何をしたのかを見ていきたいと思います。
画像を最適化する
「画像を最適化する」は要するに画像を圧縮しましょうということです。画像圧縮は、gruntやgulpのようなタスクランナーに任せるのが最適だと思います。
ただ、grunt-imageのようなプラグインを使った場合、何も考えずにjpeg画像を圧縮すると、PageSpeed Insightsが求める圧縮率に達しないことがあります。また過度に圧縮して画像が潰れてしまわないように注意したいです。optimizerでjpegRecompressを追加し、色潰れが起きないように目視でクオリティーを調整する必要があると思います。
ブラウザのキャッシュを活用する
「ブラウザのキャッシュを活用する」は、Expiresヘッダーを指定してブラウザキャッシュを活用することが主になりますが、長期間開発・運用されているサイトだと、それ以前に不要なファイルを削除するプロセスが必要かもしれません。私が運用に関わっているサイトでは、使われていない広告タグが複数あり削除するだけでスコアは上がりました。その上でサーバーサイドでExpiresを1週間以上に設定し、画像やJS、CSSファイルの末尾にパラメータをつけアセットの更新を確実に行えるようにしなければなりません。
インライン画像やCSSにパラメータを付与するのはサーバーサイドのスニペットで対応して頂き、フロントエンド側では、htmlにロードされているJSとCSS内の画像URL末尾にパラメータを付与しました。その際使ったのが、grunt-asset-cachebusterというgruntプラグインです。gruntでbuildするタイミングでgetTimeからパラメータを作成し、CSS内の画像URLにパラメータを付与しました。弊社の開発体制では、ステージング環境にdeployされるタイミングでgruntがbuildされるので、そのときパラメータが付与されることになります。
スクロールせずに見えるコンテンツのレンダリングをブロックしているJavaScript/CSSを排除する
この項目は、JavaScript/CSSを出来るだけひとつまとめる and JavaScriptを非同期で読み込むように対策することになります。 JavaScript/CSSをひとつまとめるのは、webpackやgrunt/gulpで基本的に対応できると思います。
CSSファイルを出来るだけひとつにまとめることが大事ですが、まとめきれないCSSが小さいサイズ(具体的には14KB以下)であるなら、htmlにインライン化する方法もあります。
だだし、たとえCSSをひとつにまとめたとしても、その最後のCSSがレンダリングをブロックしている状況は変わりありません。このCSSを非同期で読み込めば良いと考えるかもしれませんが、そうするとCSSが読み込まれる前にhtmlがレンダリングされるのでCSSがあたっていないhtmlが一瞬ちらつくことになってしまいます。
この対策として考えられるのが「クリティカルCSS」という考え方です。ちらつきがおきないようにファーストビューの小さなCSSだけをインライン化して先に読み込み、その他のCSSは非同期で読み込みます。grunt-critical を使えば自動的にクリティカルCSSを作成できます。しかし、留意すべきなのはファーストビューに必要なCSSだけだとしても、サイトによっては巨大になることがしばしばあるでしょう。また、クリティカルCSSの作成を自動化したとしても、レイアウトの異なるページが複数あるとbuildタイムが肥大化するのも厄介な点です。弊サイトでは、他の対策をしてスコアが85以上になったのでクリティカルCSSを採用するまでに至りませんでした。
JavaScriptの非同期読み込みに関しては、まずscriptタグにasync属性やdefer属性をつけて読み込む対策が考えられます。async属性やdefer属性をscriptタグにつけると、JavaScriptを非同期に読み込むようになりレンダリングをブロックしません。注意点としては、scriptタグを読み込む順番を担保する必要があるときはasync属性でなくdefer属性をつける必要があります。 またasync属性やdefer属性に対応していないブラウザを考慮する必要がある場合は、下記のようにcreateElementでscriptオブジェクトを作成してDOMに追加する方法もあります。
var s = document.createElement('script'); s.type = 'text/javascript'; s.src = 'https://◯◯.js'; document.getElementsByTagName('head')[0].appendChild(s);
ライブリを使いJavaScriptファイルを非同期で読み込む方法もあります。LABjsを使えばIE8以下の対応が必要なサイトでも問題なく非同期読み込みを実現できます。
JavaScriptを非同期に読み込むうえでひとつネックになるのは、広告タグのような外部サーバーにあるJavaScriptを読み込んでいる場合です。管理外にあるのでできる対策は限定的です。広告タグを発行しているベンダーが非同期読み込み対応のタグを再発行している場合があるので調べてみるとよいでしょう。 あまりお勧めしませんが、PageSpeed Insightsのユーザーエージェントをみて弾くという方法もあります。
if(navigator.userAgent.indexOf("Speed Insights") == -1) { //外部サーバーにあるJavaScriptをここで読み込む }
PageSpeed Insightsのみ狙い撃ちで対応する方法なので、弊サイトでは導入しませんでした。繰り返しになりますがあまりお勧めではありません。
html圧縮
htmlの圧縮は、インデントや空白の削除を行います。これもタスクランナーなどで自動化することをお勧めします。ローカル開発環境でhtmlを圧縮してしまうと開発時の可読性が大幅に下がるので、ステージングでbuildするタイミングでhtml圧縮するタスクを動かすとよいと思います。個人的にはhtmlを圧縮するのは好みではなく最低限の圧縮にしたかったので、grunt-contrib-htmlminを使いスコアを上げるために空白やインデントを削除するなど最低限かつ効果のある設定にしました。下記のようなオプションの設定でPageSpeed Insightsからは合格点を貰えるはずです。
htmlmin: { dist: { options: { removeComments: false, collapseWhitespace: true, preserveLineBreaks: true, minifyCSS: true, minifyJS: false, keepClosingSlash: true }, 〜省略〜 } },
最後に
今回はフロントエンドの対策を中心に書きましたが、データベースのパフォーマンスチューニングは当然必要になると思われます。またPageSpeed Insightsのスコアへの貢献度は不明確でも重要な項目はあります。例えば、HTTP/2への切り替えなどがそうでしょう。HTTP/2対応したことでサイトパフォーマンスは明白に向上しましたが、PageSpeed Insightsのスコアが向上したかどうかは定かではありません。PageSpeed Insightsはあくまでひとつのベンチマークであることを意識しつつ、UX向上への道標として活用を考えてみてはいかがでしょうか。
アスタミューゼでは、エンジニア・デザイナーを募集中です。ご興味のある方は遠慮なく採用サイトからご応募ください。お待ちしています。