Kekeの日記

エンジニア、読書なんでも

ポートフォリオサイトを爆速化する

はじめに

私は、インターンシップなどの選考に備えて、以前自分のポートフォリオサイトなるものを作りました。

しかし、あまりに速くデプロイしたかったことから、パフォーマンスについて一切無視した結果、とてつもなく遅いサイトができてしまいました。

結局、他人に見せるには恥ずかしいサイトになってしまい、今回の記事で爆速にできればと思います。

当サイトはこちらです。

サイトが遅くなる主な原因

  1. ネットワークに関することです。ブラウザでコンテンツをリクエストすると、ネットワークを介してレスポンスが返ってきます。通信速度などの影響を受けるので、速度計測ツールなどによって検証が必要です。

  2. レンダリングに関することです。画像などのデータはラスタライズされて表示されますが、一例として、画像が非常に大きいと、その時間もかかってしまいます。特に、リッチなアニメーションを導入していると、ボトルネックになりがちです。レンダリングの効率について検証する必要があります。

  3. スクリプト処理に関することです。これは主にJavascriptを指します。特に、ロジックについては注意が必要です。 使用メモリなどを検証する必要があります。

0. 実際に遅いのかを定量的に調べる

まず、自分のサイトがどのくらいの時間でレスポンスを返すのかを調べます。

Google Chromeの「デベロッパーコンソール」のNetworkタブで調べることができます。

ここでキャッシュがない状態で設定したいので、Disable Cacheにチェックボックスをいれます。

スクリーンショット 2018-08-18 8.29.55.png

すると計測結果が下に表示されます。

スクリーンショット 2018-08-19 1.29.16.png

めちゃめちゃ遅いです、、、 そもそも遅くても1.0秒が閲覧者のUXにもいいということなので、至急改善しないといけません。

また、全体的なサイトの評価は、"Audit"タブで測定することができます。

スクリーンショット 2018-08-18 19.58.06.png

ターゲット端末、指標、通信状態を決めて評価します。20秒ぐらいかかりました。

まず、最初にモバイル端末から調査しました。

スクリーンショット 2018-08-18 20.01.44.png

やはり、パフォーマンスが非常に悪いです。

しかしながら、タグを適切に使うなど、SEO対策はしたつもりだったので、かなりスコアはいいです。

提案は以下の通りです。

スクリーンショット 2018-08-18 20.05.00.png

ネットワークのペイロードに問題があるみたいです。

デスクトップも調査してみると

スクリーンショット 2018-08-18 20.13.59.png

同様の結果です。

1. ネットワークに関して

まず、ネットワーク処理の3原則は以下の通りです。

  • データの転送量は小さく
  • データの転送回数は少なく
  • データの転送距離は短く

また、ブライザの内部構造を知る中でも、クリティカルレンダリングパスは非常に重要です。

スクリーンショット 2018-08-18 8.40.52.png

ここでは、Networkタブで、「どのような通信があり」、「どのくらい時間がかかったか」を調べます。

重要の指標としては、Status, Size, Time, Waterfallです。

説明は不要かと思いますが、Waterfallとはリクエストのダウンロードの処理の詳細と、かかった時間のことです。

特にこのサイトだと、以下のような画像が非常に遅いことがわかります。

スクリーンショット 2018-08-18 9.17.23.png

  • 遅い画像は明らかにデータサイズが大きい

ので、データサイズを改善する必要があります。各々の詳細は項目を選択し、Timingタブを見ることで設定できます。

スクリーンショット 2018-08-18 9.48.24.png

TTFBは、最初の1バイトがくるまでの時間を表しています。 6msであり、フロントエンドエンジニアが何かできることはありません。

サーバーサイド、インフラの経験からクラウド環境のネットワークを考えることもできるとは思いますが、、、

やはり、コンテンツのサイズが非常に大きいのでダウンロードに時間がかかっているのでしょう。

これは、レンダリングのところで再度指摘します。

特に、通信のオーバーロードがかかっているわけではないので、ネットワーク処理としては大丈夫そうです。

他にも改善方法としては、

  • 画像の遅延ダウンロード。
  • 不要なライブラリどを削除するなど何かできると思います。

2. レンダリング処理に関して

レンダリングの原則は以下の通りです。

  • 1フレーム内の処理を軽くすること。60FPS以上が理想的です。
  • ブラウザの内部処理を利用して最適化を測ること

特に"Performance"で知ることができるので使ってみます。 Recordを押して記録をはじめ、適当にスクロールなどをしたら停止しましょう。

8秒ほど録画しました。 しかし、アニメーションが皆無なので特に問題そうなところはありません。

スクリーンショット 2018-08-18 20.32.55.png

すこし大事な箇所を解説をします。

ここでもネットワーク処理について知ることができます。 スクロールなどをして画像が読みこまれるなど、ネットワーク処理が期待される場合に、調べることができます。

スクリーンショット 2018-08-18 20.35.17.png

また、全体として、どのくらいスクリプト処理、ペイント処理、レンダリングに費やしているかを知ることができます。

ペイント処理とは、CSSなどでbox-shadowなどの比較的に重い処理のことです。一般的には問題になることはありませんが、あまりにも多用しすぎると重くなるので注意が必要です。

スクリーンショット 2018-08-18 20.40.12.png

しかし、やっぱりレンダリング処理が重いです。

2.1 ペイント処理に関して

ここだけ、副セクションを定義して調査したいと思います。

レイアウト算出と同様に、"Performance"が参考になります。 ここで"Enable Advanced paint instrumentation"をチェックしてください。

以下が測定した結果です。

スクリーンショット 2018-08-18 21.57.16.png

これによって具体的なCSSの何が遅いのかを知ることはできません。 適宜、遅いところを調査することになります。

3. スクリプト処理に関して

スクリプト処理の原則は以下の通りです。

  • UIブロッキングをするような処理を避ける
  • メモリリークを検出し、節約するようにする

javascriptはメインスレッドで実行するので、その間はレンダリング処理をすることはできないので、その間は塞がれることになります。

メモリリークの調査をします。 ヒープ領域の調査は"Memory"タブで計測することができます。

また、重い処理は再度"Performance"で調べることができます。

ここでは、スクリプト処理をしていないので本記事では省略します。

実際に問題を直す

1. 画像を圧縮する

Vue.jsでは、プロダクション環境ではすでに圧縮されています。 なので、元の画像の次元数を減らさなければなりませんので、すべて約50%縮小しました。

再度、AuditとPerformanceによる評価をします。 ここではモバイルで検証します。

スクリーンショット 2018-08-20 3.11.46.png

ポイントが時間に対して線形ではないのですが、特にいいスコアを出していますね。 また、ネットワークの方は、画像群がかなりボトルネックになっていますね。

image.png

次にコンテンツが下のものは遅延ローディングを実装します。

まずは画像ファイルから。パラパラ読み込まれていく様子がわかります。

hoge.gif

今回速度を計測すると、たまに1.2秒を下回るくらいです。

スクリーンショット 2018-08-20 3.43.14.png

同様にはてなブログの記事も、遅延ローディングしました。

スクリーンショット 2018-08-20 11.59.59.png

ここでキャッシュを使わずに、約0.8秒を実現しました。

また、コンテンツをGoogle Cloud Storageに保存しました。 無料枠をすべて使ってしまっていたので同じファイルに保存していました。

スクリーンショット 2018-08-20 12.03.24.png

Auditスコアはこちらです。

スクリーンショット 2018-08-20 12.14.16.png

まとめ

  • ネットワーク処理は、基本的にhttp通信に関すること
    • ブログうめこみなど、ボトルネックがある可能性がある
  • サーバーサイドなどの経験があれば、イベントリスナーなどくらいしかスクリプト処理は問題にならないはず
    • といれど、forなどがあれば計算量を想定すべき
  • レンダリング処理は、特に画像を正しく用意しないとボトルネックになりがち
    • 数MB単位の画像を使っているサイトもあったり、以外に対策法は多様である。

もちろん速度は大事ですが、それはUXが何より大事だからです。 1秒以上待たされるけど、ローディングアニメやプログレスバーがリッチだったら、逆にたち時間は短く感じるかもしれません。

まだまだそっちの方面で勉強しないといけないと痛感しました。

追加

SEOやBest Practiceなど他の指標

1.metaタグを付与 2.alt属性を付与 3.lang属性を付与

結果は以下の通りです。

スクリーンショット 2018-08-20 12.40.06.png

PWAやブラウザ特化の最適化はできるだけしたくないので、終わります。