吉川 徹

HTML5 Experts.jpはなぜこんなにパフォーマンスが悪いのか…全てお見せします!ーWebパフォーマンス改善企画(改善編)

Webパフォーマンス改善企画(改善編)は、実際の改善内容とその結果をお伝えします!パフォーマンス分析を行った解析編は、こちらからご覧ください。本記事はHTML5 Experts.jpがいかにして速くなったのかを包み隠さずお伝えします!

今回の前提条件と改善ポイント

実際の改善を行う前にいくつか前提条件を説明しなければいけません。まず動作環境ですが、HTML5 Experts.jpは、WordPress上で動作しており、改善内容はプラグインの導入やPHPのコード修正が主になっています。ただ、そういったWordPressの泥臭いチューニングは本題ではないので、細かく解説するのではなく大まかな改善内容とその方針を説明したいと思います。また、改善内容に関しても費用対効果がある程度高いものを優先しているため、まだまだ改善できるというところも、あえてそのままにしているところもあります。

今回の改善内容は、前回の分析結果から以下のようになっています。その分析内容などについては解析編をご確認ください。以下の改善ポイントとその順番に沿って解説していきます。(順番は、改善内容の導入のしやすさや影響の大きさなどを考慮して実際に実施した順序になっています)

改善ポイント

  1. ソーシャルメディア系サービス(シェアボタンなど)のパフォーマンスを改善する
  2. 実際の表示サイズより大きな画像は適正なサイズに変更する
  3. マークアップを改善する(書き方やJSのミニファイ等)
  4. WordPressのキャッシュを導入する
  5. Keep Aliveが全ての環境で効いているか、設定時間は適切かを確認し、コンテンツダウンロード時間を最適化する

ソーシャルメディア系サービスのパフォーマンスを改善する

まず最初に着手したのは、ソーシャルメディア系のガジェットなどです。HTML5 Experts.jpでは、トップページにはTwitterのタイムラインとFacebookのウィジット、記事ページには、各種シェアボタンとFacebookのコメントを埋め込んでいました。これらのソーシャル系のガジェットは、多数のリソースを読み込んだり、スクリプトによるメインスレッドのブロッキングなどでユーザーの体感スピードを劣化される主たるものです。まずは、不要なガジェットの整理ということで、ほぼ利用がなく効果が不明なTwitterのタイムライン、Facebookのウィジット、Facebookのコメントは完全に削除することにしました。これだけで、トップページからはソーシャル系のガジェットが完全になくなることになります。次に記事ページのソーシャルボタンですが、ソーシャルボタンのスクリプトを読み込まないように自作することにしました。現在(改善後)のソーシャルボタンは次のようになっているはずです。

PC版ソーシャルボタン

PC版ソーシャルボタン

モバイル版のソーシャルボタン

モバイル版のソーシャルボタン

これらのソーシャルボタンでは、例えばTwitterのツイートなどを直接リンクで指定しており、onclickで小さいウィンドウが開くように変更しています。そのため、APIを利用しなければ実現できないFacebookの「いいね」と、Google+の「+1ボタン」は、いずれもシェアボタンに変更しています。各ボタンのカウント数については、サーバー側でキャッシュして表示する「SNS Count Cache」というプラグインを導入して利用しています。

ソーシャルメディア系のガジェットの改善は非常に効果が大きく、以下のようにPC版の記事ページでは、ページの読み込み時間が5秒近辺だったものが、2.5秒のほどに劇的に改善しています。また、バラツキがあった計測時間が小さい範囲に収まるように収束しています。

PC版記事ページの読み込み時間(折れ線グラフ)

PC版記事ページの読み込み時間(折れ線グラフ)

PC版記事ページの読み込み時間(スキャッタプロット)

PC版記事ページの読み込み時間(スキャッタプロット)

実際の表示サイズより大きな画像は適正なサイズに変更する

次は画像サイズの縮小です。HTML5 Experts.jpでは既に画像の最適化を行う「EWWW Image Optimizer」プラグインを導入済みでしたが、画像のサイズ自体はあまりケアしていませんでした。そのため、記事によっては原寸サイズの画像を貼り付けているものもあり、ダウンロード容量が非常に多いページもありました(WordPressの場合、画像を挿入する際にサイズを選択できます)。また、お恥ずかしながら、アイキャッチ画像を設定している記事については、記事一覧でサムネイルに原寸サイズの画像が表示されるというバグも見つかりました。そこで、以下のように対応することに決めました。

  • 画像の最大サイズをPC版記事ページの横幅に合わせ640pxとする
  • 画像の最大サイズより大きな画像がアップロードされた場合、強制的にリサイズする
  • 記事一覧で、適切なサイズのサムネイル画像を表示するように変更
画像の最大サイズ

画像の最大サイズ

記事一覧のサムネイル画像

記事一覧のサムネイル画像

まず初めに、画像の最大サイズを変更します。WordPressでは画像のサイズを設定画面で変更することができ、デフォルトでは「大サイズ」の設定値は1024×1024に設定されている部分を640×640に変更します。しかし、これだけでは編集者が誤ってフルサイズの画像を挿入することができてしまうため、それより大きい画像がアップロードされた場合に強制的に640×640にリサイズするようにします。これは、「Imsanity」というプラグインを導入することで解決しました。

次に、記事一覧で適切なサイズのサムネイル画像を表示するように変更します。PC版の場合、サムネイル画像の表示サイズは幅207pxとなっていたため、それに合わせて画像をアップロードする際に自動的に幅207pxのサムネイル画像を作成するように変更しました。同時に、記事一覧を出力する際にサイズを指定して画像を表示するようにコードを修正しています。(これらの詳細なコードは例示しませんが、add_image_size the_post_thumbnail wp_get_attachment_image_src 等のキーワードを調べていただければ見つかるかと思います)

ここでモバイル版について考慮されていないと気がついた方がいらっしゃるかもしれません。モバイル版のサムネイル画像のサイズは、幅93pxとなっていましたが、これをこのまま適用してしまうと高精細なディスプレイではぼやけてしまうため、そのままPC版と同じものを表示するようにしました。本来であれば、レスポンシブイメージを採用するのが理想だと思いますが、この時点ではリソースの問題から断念しています。

最後に、既存の画像ファイルに対して、これらの変更を反映する必要があります。最大サイズの変更と新たなサムネイル画像の表示サイズの追加については、「AJAX Thumbnail Rebuild」というプラグインを使ってバックグラウンドですべて処理しました。その後、「Imsanity」、「EWWW Image Optimizer」プラグインについても、既存の画像に対するオプション機能を使って再処理を実施しました。これで、すべての画像は適正なサイズに変更されたことになります。

マークアップを改善する(書き方やJSのミニファイ等)

ここで実施するのは、不要なスクリプトやスタイルを整理したり、ファイルの結合やミニファイなど、一般的なWebパフォーマンスのベストプラクティスに近いものです。しかしながら、WordPressではすべてのページでjQueryを読み込んでいたり、いろいろなプラグインがそれぞれファイルを読み込んでいたりと、かなり奔放な状況です。そのため、実際の作業はここが一番泥臭く、複雑なものになりました。改善内容は、主に以下のようなものです。

  1. すべてのページで読み込んでいるスクリプト、スタイルを調査する
  2. 不要なスクリプト、スタイルを削除する
  3. スクリプト、スタイルの移動、結合とミニファイ(「Autoptimize」プラグイン)

まず、1番と2番ですが、初めにすべてのページで読み込んでいるスクリプト、スタイルを調べます。HTML5 Experts.jpの場合、主にトップページ、記事ページ、その他のページの3種類になります。その他のページにもいくつか種類がありますが、スクリプト・スタイル構成は似たようなものになるので、ここでは省略しています。また、上記3種類がそれぞれPC版、モバイル版とあるので計6種類ということになります。これらの各ページでは、HTMLソースコード内のべた書き(scriptタグなど)やWordPress上で読み込まれているリソース、実際にブラウザに表示されているページ上で読み込まれているファイルなどを調べます。(WordPress上では、wp_enqueue_scriptsをフックしてそれぞれのハンドル名を表示します)

その後に、どのプラグインが読み込んでいるのか、それらは本当に必要かどうかを判断します。プラグイン自体が不要であればプラグインを削除し、スクリプトやスタイルの読み込みのみを止めたいのであれば設定変更で対応可能か判断し、最終的にはWordPress上で個別の種類のページに対してスタイルを削除します。例えば、「Facebook」公式プラグインは、すべてのページでFacebookのスクリプトを読み込むようになっており、ソーシャルボタンを廃止した関係もあって完全に削除しています。その際にプラグインが提供していたOGP設定などは手動で追加しています。また、モバイル版のトップページではjQueryは不要のため、トップページでのみjQueryを読み込まないといった形になっています。(WordPress上では、wp_enqueue_scriptsをフックしてif文でそれぞれのページ上でwp_dequeue_scriptwp_dequeue_styleなどでスクリプトやスタイルを読み込まないようにしています)

そして肝心の改善結果ですが、実は問題があり、ページのHTTPリクエストから最初のデータが返ってくるまでの時間(TTFB: Time To First Byte)が遅延するという事象が発生しました。これは、元々WordPressではDBアクセスなどがあり、時間がかかっていた箇所でしたが、加えて今回のAutoptimizeがファイルの結合、ミニファイを行うためにバッファを読み込んで処理している関係でさらにTTFBが伸びるという結果になりました。そのため、スクリプト・スタイルのファイル数とサイズが減ったにも関わらず、結果としてパフォーマンスは相殺され、逆にロード時間が若干長くなるという状態になりました。そのため、Autoptimizeを導入する場合は、基本的には後述するキャッシュを導入する必要があるという結論となりました。

TTFBの遅延(ウォーターフォール図)

TTFBの遅延(ウォーターフォール図)*青い部分がTTFB

WordPressのキャッシュを導入する

WordPressは、簡単にページを構成して表示できる反面、PHPの処理やDBアクセスが発生するため、TTFBが遅くなりがちです。そのため、HTML5 Experts.jpのような、ある程度表示内容が変わらないサイトの場合はキャッシュプラグインを導入するのが望ましいでしょう。今回、キャッシュプラグインには、ページキャッシュ、オブジェクトキャッシュ、DBキャッシュの3つが可能な「W3 Total Cache」と、WordPressのUIの日本語化のための翻訳ファイルをキャッシュする「MO Cache」を導入しました。いくつかあるキャッシュプラグインのうち、W3 Total Cacheを採用した理由は、現在PC版、モバイル版のテーマを「Multi Device Switcher」でブラウザ(UA)によって切り替えていますが、W3 Total CacheにはUser Agent Groupごとにキャッシュできる仕組みがあることです。

これにより、現在はアクセスのある記事ページなどは、キャッシュが1時間保持されるような設定になっています。キャッシュは記事が公開されるとクリアされ、再度アクセスがあるとキャッシュされるようになっています。そのため最初に記事にアクセスした人は若干遅いと感じることがあるかもしれません。また、ソーシャルボタンなどのカウント数も即時には反映されなくなっています。

キャッシュを導入した結果、なんと2〜3秒かかっていたTTFBが100ms前後にまで改善しました。体感速度でもかなり快適に表示されるように、非常に高い効果がありました。

TTFBの改善(ウォーターフォール図)

TTFBの改善(ウォーターフォール図)

Keep Aliveが全ての環境で効いているか、設定時間は適切かを確認し、コンテンツダウンロード時間を最適化する

モバイルでKeep Aliveが効いていない問題については、結論からいうと、HTML5 Experts.jpで利用しているHTTPサーバーであるnginxの仕様が問題となっていました。元々、SafariにはKeep-Aliveが効いていると、ファイルがアップロードできないというバグ(該当のissueはこちら)があり、それに対応する形でnginx側はSafariに対してデフォルトでKeep-Aliveを無効にするという対策を取っています(keepalive_disableの設定)。HTML5 Experts.jpでは、ユーザーがファイルをアップロードするユースケースはないので、nginxの設定に”keepalive_disable none;”を指定してKeep-Aliveの無効を取り消しています。また同時に、Keep-Aliveのタイムアウトをデフォルトの75秒から20秒に変更しています。これは、現状の読み込み完了までの時間が20秒を超えることはほぼないためです。

その結果、モバイルでも同時接続数分のコネクション(別ドメインの接続を除く)を確保した以降は、Initial Connectionが消え、全体で2秒近く高速になりました。これを見ると、別ドメインへのアクセスを整理することによってもう少し効率化できそうではありますが、今回はここまでとしました。

モバイルのタイムライン(ウォーターフォール図)

モバイルのタイムライン(ウォーターフォール図) *Initial Connecctionはオレンジ色の部分

まとめ

これまで5つの改善ポイントについて、記事中の通り改善を実施してきました。これによってどのようにパフォーマンスが改善したのかを、この企画における全期間中のパフォーマンストレンドの推移でご覧いただきたいと思います。

全期間中のパフォーマンストレンドの推移(PC版)

全期間中のパフォーマンストレンドの推移(PC版)

全期間中のパフォーマンストレンドの推移(モバイル版)

全期間中のパフォーマンストレンドの推移(モバイル版)

いずれも大きく改善され、PC版では5秒台から2秒以下に、モバイル版では20秒前後で大きく揺れていたものが安定して8秒近辺に落ち着いています。これらの結果を受けて、解析編で掲げた改善目標が達成されているかどうかを、個別のデータで確認していきたいと思います。

改善目標

  1. Total Time(サイトにアクセスした時点からブラウザ上でコンテンツ表示が完了するまでの時間)は2秒を切る
  2. アクセスした際のTotal Timeに関する品質を一定にする(ばらつきをなくして一定にする)
  3. 3G回線からのTotal Timeに関するアクセス品質をブロードバンド回線のそれに近づける

まずは、改善後のPC版の各ブラウザの計測結果を見ていきましょう。 次のグラフは、トップページの1日の計測結果です。(時間帯によってはネットワーク品質に揺れがあり、計測結果が多少上下します。)

PC版のTotal Time(折れ線グラフ) *Chrome、Firefox、IE

PC版のTotal Time(折れ線グラフ) *Chrome:黄色、Firefox:青、IE:赤

それぞれの平均Total Timeは、Chromeが1.59秒、Firefoxが1.657秒、IEが1.125秒という結果となりました。当初目標の「Total Timeは2秒を切る」という点では、余裕を持ってクリアしています。特にIEの場合、1秒を切るケースもあり非常に高速です。次に同じデータをスキャッタプロットで分布を見てみましょう。

PC版のTotal Time(スキャッタプロット) *Chrome:薄緑、Firefox:オレンジ、IE:青

PC版のTotal Time(スキャッタプロット) *Chrome:薄緑、Firefox:オレンジ、IE:青

スキャッタプロットで見ると、各点がきちんと下に寄っているのがわかります。はずれ値も少し見られますが、およそ95%の計測値が2.5秒以下の範囲に収まっています。そのため、「アクセスした際のTotal Timeに関する品質を一定にする」も達成していると言えるでしょう。

最後に改善後のモバイル版のトップページの計測結果を見ていきます。次の2つのグラフは、3G回線でのXperiaとiPhone6S、参考としてLAN環境でのiPhone6を加えたものです。

モバイル版のTotal Time(折れ線グラフ) *Xperia(3G):オレンジ、iPhone6S(3G):赤、iPhone6(LAN):青

モバイル版のTotal Time(折れ線グラフ) *Xperia(3G):オレンジ、iPhone6S(3G):赤、iPhone6(LAN):青

モバイルの場合、ネットワーク品質の揺れ幅が大きくなりますが、平均ではXperiaが12.863秒、iPhone6Sが8.601秒となっています。参考値であるLAN環境のiPhone6が平均0.486秒であることを考えると、3G回線がパフォーマンスに大きく影響していることがわかります。これは、画像ファイルの数、ダウンロード容量が多いためで、ネットワークに遅延が発生すると大きく影響します。この時の画像ファイル数は38で、サイト全体の容量は400KB程度になっています。これは、HTML5 Experts.jpのメディアの特性を考えると、ある程度はやむ得ないと思いますが、もう少し減らせるように工夫すべきかもしれません。救いとしては、遅延の原因が画像ファイルにあるので、ファーストビューへの影響は比較的少なく、体感速度は数値よりも早く感じるという点でしょうか。

モバイル版のTotal Time(スキャッタプロット) *Xperia(3G):薄緑、iPhone6S(3G):オレンジ、iPhone6(LAN):オレンジ

モバイル版のTotal Time(スキャッタプロット) *Xperia(3G):薄緑、iPhone6S(3G):オレンジ、iPhone6(LAN):オレンジ

スキャッタプロットのほうを見ると、3G回線のために値の範囲が広がっていますが、概ね下に寄っているように見えるので許容範囲内であると言えるかと思います。しかしながら、前述の問題から「3G回線からのTotal Timeに関するアクセス品質をブロードバンド回線のそれに近づける」については、大きく改善してはいるものの課題が残っているという結論としたいと思います。

皆さん、いかがでしたでしょうか。本記事で改善した結果は是非、皆さんの手で体感していただければと思います。HTML5 Experts.jpでは、これからもパフォーマンス改善を続けていきますので、HTML5 Experts.jpを今後とも宜しくお願いいたします。また、この企画に大変なご協力をいただいた株式会社Spelldata竹洞陽一郎さんにこの場を借りて厚くお礼申し上げます。ありがとうございました!!

補足事項

本記事で扱っている計測結果は、改善実施直後の数値です。現在の数値とは異なることがあることをご了承ください。特に本記事の内容より以降に、HTTPS(SPDY対応)化を実施しており、Total Timeは全体的に伸びています。そのあたりの対応についても、別の機会で紹介できればと思います。

Powered byNTT Communications

tag list

アクセシビリティ イベント エンタープライズ デザイン ハイブリッド パフォーマンス ブラウザ プログラミング マークアップ モバイル 海外 高速化 Angular2 AngularJS Chrome Cordova CSS de:code ECMAScript Edge Firefox Google Google I/O 2014 HTML5 Conference 2013 html5j IoT JavaScript Microsoft Node.js Polymer Progressive Web Apps React Safari SkyWay TypeScript UI UX W3C W3C仕様 Webアプリ Web Components WebGL WebRTC WebSocket WebVR