Webフロント周りのパフォーマンスを計測・チューニングする

Github Pagesで公開しているポートフォリオサイトがそんなに色んな情報載せてる訳でもないのですが、遅くてあまり気持ちのいいものではないので、最適化していきます。

結論から書くと、2.87sぐらいかかっていた読み込みが1.57sぐらいになりました。 まだまだ細かいチューニングの余地はありますが、コストのわりに効果の大きそうなところを探って対処してみました。

  1. Chrome Developer Tools, Page Speed Insightsとかで原因を探る
  2. JavaScriptのminify
  3. 大きい画像はプログレッシブ形式のJPEGに変換
  4. ImageOptim
  5. CloudFrontでCache, 配信, HTTP/2対応

タイトルにはチューニングと書きましたが、基本的な最適化をちゃんとすればちゃんと表示速度が改善された感じです。

計測

まずは現状を確認

f:id:nwpct1:20161125170524g:plain

大きなヘッダ画像があるのでそこの読み込みが気になりますね。

Chrome Dev Tools

f:id:nwpct1:20161125170852p:plain

読み込み完了まで、2.87s。 グラフを見ると、bundle.js(このポートフォリオでは、Angular2 + TypeScriptを使ってます)とヘッダ画像が大きく特に読み込みに時間がかかっていることがわかります。

Page Speed Insights

Web Site: https://developers.google.com/speed/pagespeed/insights/?hl=ja

  • Mobile: Speed 56/100
  • Mobile: User Experience 97/100
  • PC: Speed 76/100

バイルの表示が特に遅いですね。 Google先生からのアドバイスは、

Web Pagetest

Web Site: https://www.webpagetest.org/

海外とかいろんな環境でのサイトのパフォーマンスをチェックできるらしい。 このページからのアドバイスは、

  • CDNを使う
  • 画像を圧縮する
  • 静的コンテンツをキャッシュする

最適化

JSのminify

まずは手軽で効果のありそうなところから。 webpackのhelpを見たら --optimize-minimize というオプションがあったので有効に。

webpack --optimize-minimize ./src/ts/index.js --output-filename ./public/js/bundle.js

f:id:nwpct1:20161125174452p:plain

  • bundle.jsのファイルサイズ: 592kB > 277kB
  • bundlejsの読み込み時間: 1.31s > 753ms
  • Page Speed Insights Mobile Score: 56点 > 59点
  • Page Speed Insights PC Score: 76点 > 87点

580msぐらい速くなりましたね。

ヘッダ画像の改善

プログレッシブ形式のJPEGに変換

905KBもあるのでこれも改善できそうですね。 JPEGには、左上から画像をパラっと読み込んでくれるベースライン形式と最初はモザイクが出るプログレッシブ形式があるみたいです。プログレッシブ形式のほうがユーザ体験は良いと言われているそうです。

最初のGIF画像を見てもらうと分かるのですが明らかにベースライン形式の挙動を示していますね。 rdjpgcomというツールで確認、imagemagickで変換出来るみたいです。

$ rdjpgcom -verbose img/eyecatches/autumn_leaves.jpg
JPEG image is 1500w * 1000h, 3 color components, 8 bits per sample
JPEG process: Baseline
$ convert img/eyecatches/autumn_leaves.jpg -interlace JPEG progressive.jpg
$ rdjpgcom -verbose progressive.jpg
JPEG image is 1500w * 1000h, 3 color components, 8 bits per sample

f:id:nwpct1:20161125180721g:plain

うーん、確かにモザイクが出るプログレッシブ形式ですね。ただユーザ体験がいいかというとなんとも言えない感じです。 よくなったのかイマイチ実感できないので、画像サイズを落としてみましょう。 画像サイズが小さくなって読み込みが早くなれば、わかりやすく快適になってくれそうです。

Optimで画像サイズを小さくする

Web Site: ImageOptim — better Save for Web

JPEG Miniは高いので、Optimを使って画像サイズを減らしてみます。 メタ情報やカラープロファイルを削除するらしいです。

  • 画像サイズ: 905KB > 817KB

まだ結構でかいですね。 この画像、1500x1000だったのですが、横幅1280pxぐらいが多いみたいなので思い切って減らしてみます。

  • 画像の読み込み時間: 1.47s > 988 ms
  • 画像のサイズ: 905KB > 626 KB
  • Page Speed Insights Mobile Score: 59点 > 63 点
  • Page Speed Insights PC Score: 変化なし

まだ少し重い気もしますが、横幅いっぱいに広げる画像なのである程度は仕方がないかもしれません。 別のところに手を付けます。

CloudFrontでCache, HTTP/2対応

Web Pagetestの結果では、海外からアクセスした際にレイテンシが大きいのか、CDNを使えとのメッセージがありました。 HTTP2のストリーム多重化で速くなることも期待して、AWS CloudFrontをかませてみます。 (余談: HTTP/2を使うかHTTP/1.1を使うか、どうやって判断するのか調べてみたんですが、TLSネゴシエーションの際にHTTP/2が使えるか確認してくれるみたいですね)

今回は検証目的なので、 http://c-bata.link は一旦そのままでこのURLをoriginにしてCloudFrontをかませます。 Webフォントをhttpで読み込んでいる部分があるのでそこを修正してCloudFrontのCacheをInvalidate後、何度かリロードする(Cacheさせる)と全体の読み込み時間: 1.57sまで上がりました。

f:id:nwpct1:20161126165720p:plain

グラフを見る限り、HTTP2のストリーム多重化がかなり効いているような気がしますね。

おわりに

最終的な表示はこのようになりました。 CloudFront対応はドメインと証明書の問題で、まだ http://c-bata.link のほうには反映していませんが、CloudFront経由後は読み込み速度が約半分の1.5s程度になり、GIFアニメーションの通り体感的なスピードも改善されたようです。

f:id:nwpct1:20161126170433g:plain

ハイパフォーマンスWebサイト ―高速サイトを実現する14のルール

ハイパフォーマンスWebサイト ―高速サイトを実現する14のルール

WEB+DB PRESS Vol.95

WEB+DB PRESS Vol.95