Webパフォーマンス

2020/09/22に公開

Webパフォーマンスチェックリスト

Webパフォーマンスは、80%から90%がフロントエンド側で発生していると言われています。そのため、この記事のチェック項目は、ほとんどがフロントエンド側になります。WebパフォーマンスはSEOと大きく相互関係があります。しかし、この記事ではSEO観点の説明は割愛いたします。

Webパフォーマンスは、「推測するな。測定せよ」というのが重要です。そのためパフォーマンスのボトルネック(遅延の原因)は、Webサイトそれぞれです。この記事のチェック項目は、実装すれば実装前より多少の効果が見込めるベストプラクティスが主です。チェック項目を実装してもパフォーマンス全ての問題が解決されることがないことをご了承下さい。

1、CDNを利用する

CDNは、アクセスしたユーザーから(物理的に)1番近いサーバーからデータを取得してきます。CDNのデメリットは、接続先のサーバーが落ちた場合データの取得できません。その問題は、以下の方法で対策することできます。CDNからファイル取得できなかった場合、自サーバーから通常リクエストをしています。

<script src="//ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<script> 
window.jQuery || document.write(<script src="js/jquery-2.12.1.min.js"><\/script>);
</script>

DNSは、外部サーバーから取得するのでドメイン名が異なります。なので、以下のドメインシャーディングという手法にもうまく合わせることもできます。(メリット)

ドメインシャーディング

まだすべてのサイトがHTTP2.0を対応しているとは限りません。HTTP1.1は同時に接続できる数が限られています。そこで複数のホスト(ドメイン)から接続することでスピードを速めることが出来ます。しかし、複数のホストなのでDNS名前解決を行わなければなりません。効果を測定しつつ、適切なドメイン数を選定してください。

2、リクエスト数を見直す

link、script、imageタグは、外部ファイルを取得するためサーバーにリクエストをします。そのリクエスト数を見直してください。中には、同期的に読み込み必要のないファイルがあると思います。そのファイルを非同期で読み込みように変更しましょう。ファーストビューで見えないコンテンツ、ユーザーのアクションに対して表示されるコンテンツは、LazyLoadなどで非同期に変更しましょう。その他の具体的な策を記載しておきます。

  • 画像をLazyLoad(JavaScript)で非同期リクエストにする。
  • JSをdefer,async属性を利用する。
  • CSSスプライトでアイコン類を1つにまとめる。
  • レスポンシブデザインの策です。linkタグの時点で不要なスタイルはリクエストしない。CSS内でスタイルを分けるより、ファイルごと分けて不要なファイルへのリクエストは省きましょう。
<link rel="stylesheet" media="(max-width: 480px)" href="sp.css">
  • キャッシュを有効活用する。
  • imgタグのsrcset属性を利用して適切な画像を読み込む。(リクエスト数は変わらないが時間短縮になる)

3、ファイルをまとめ、圧縮する。

HTML、スタイルシート、スクリプトの(本番では)不必要なコメントや改行など削除し、複数のファイルを1つにまとめるべきです。モジュールハンドラのwebpackを使用するのが良いと思います。
圧縮は配信時に行うため、サーバーサイドの設定になります。Nginx、Apache HTTP Serverにgzip圧縮を設定することでHTML、スタイルシート、スクリプトを圧縮することができます。画像とPSDファイルは圧縮しないでください。以下は、nginx.confのgzipの設定です。

http {  
	gzip on;
	/*  略 */
}

4、画像の拡張子が適切なものになっているか。

画像は、容量を減らすことによってダウンロード時間の短縮することできます。JPEG,PNG,GIF,SVGのそれぞれの特徴を生かして使い分けてください。以下のように使い分けてください。

  • JPEG 複雑な画像や、写真に向いている。
  • PNG アイコンやUIパーツに向いている。アルファチャンネルで透過を表現することも可能。
  • GIF アニメーションに対応している。ほとんどのブラウザに対応しているのでアニメーションを表現する時は使用する。
  • SVG 拡縮してもが劣化しない。図形画像に向いている。マルチデバイスの普及に伴い期待度は上がっています。

次世代画像フォーマット

次世代画像フォーマットとは、「WebP」「JPEG200」「JPEG-XR」の3種類です。WebPは2020年6月にsafariに対応しました。IEだけ対応しておりません。しかし、ユーザーエージェントを使用して(JPEG2000と)表示分けする方法もあります。WebPの画質は、JEPGの8分の1までに抑えることもできるので検討してみてください。https://caniuse.com/webp

5、メモリリークを防ぐ

JavaScriptはメモリリークに注意しなければなりません。以下のイベントやメソッドを使用している場合は対処してください。

  • setInterval(),setTimeout()を使用している場合、イベント解除を忘れていないか。
  • console.logなどconsole系は削除する。(本番環境)
  • addEventListener(), on("click")はremoveEventListenerで解除する。Reactなどはライフサイクルフックを使用する。
  • scrollイベント、resizeイベントはユーザーがスクロール、ウィンドウサイズを変更するごとにイベントが発火します。とても重い負荷になりますので、以下のように数秒ごとにイベントを行うようにしてください。
window.addEventListener( 'scroll', sample, false );
function sample(){
	clearTimeout( timer );
	timer = setTimeout(function() {
		//処理内容
	}, 300 );
}
  • ライブラリMemoryPoolを使用できる箇所がないか確認する。

6、リダイレクトを避ける。

不必要なリダイレクトは避けるべきです。HTTPリダイレクトについては、MDNWebに掲載されています。リダイレクトとして挟んだページを読み込む時間は白紙ページが表示されることになります。ユーザー目線としては応答していないのと変わりません。対処できる場合は、すぐに対処しましょう。

<meta http-equiv="refresh" content="0; URL=http://www.example.com/" />

その他

  1. スタイルシートを読み込みは、ドキュメント(ページ)の上部に。
  2. スクリプトの読み込みは、bodyの終了タグの手前で。

この2つは、(仕様上)どうにもならない現場を見てきたため、あまり重要視していません。またボトルネックとなった案件もあまり見ていません。

  • DNSルックアップを減らす

他の策

ベストプラクティスではありません。また、実装したこともないので詳細は省きます。今後更新していきます。

  • e.preventDefault() はレンダリング処理を阻害します。touchmoveイベントリスナ内に処理が高コストであればブロッキング時間が長くなります。もし、e.preventDefault()がない場合は、addEventListenerの第3引数で宣言してあげるとPassive Listenerであることが宣言できます。
  • BEMは、クラスセレクタを強制するためCSSレンダリング処理がスムーズになります。
  • AMPの実装(工数多)

参考

  • Webフロントエンドハイパフォーマンスチューニング
  • ハイパフォーマンスWebサイト
  • 超速Webページ速度改善ガイド

Discussion