あなたのサイト遅くない？ サイトを高速化しよう！

案件で高速化について触れる機会があったので、Qiitaの方でもまとめておきます。

## サイトの表示速度の測り方について
まずは自分のサイトが遅いのかどうかを知らなければなりません。
以下サイトでは、実際に自分のサイトが遅いのかどうかを測定してくれます。体感ではわからなくても実際に測ってみると遅いということもよくあるので、一度確認してみることをオススメします。

[PageSpeed Insights](https://developers.google.com/speed/pagespeed/insights/?hl=ja)…天下のGoogle様がサイトの表示速度を測ってくれてスコアまで出してくれるよ
[WebPagetest - Website Performance and Optimization Test](https://www.webpagetest.org/)…英語だけどPageSpeed Insightsより詳細に調べることができるよ

## そもそも何でサイトが遅くなるんだ？
HTML文章をサーバーから取得してくるのに必要な時間はサイト表示時間全体の１割２割といわれています。
残りの大部分はコンポーネント（JSとか画像とかCSSとか…サイトを作るHTML以外の部分のこと）のダウンロードを待つ時間。
ブラウザはコンポーネントに対して一つ一つにHTTPリクエストを飛ばしているので、基本的にはこれらのリクエストの

- 数を減らす
- サイズを減らす

といった対策を実行して行くことになります。

HTTPについて
HTTPとはブラウザとサーバがやりとりするときの方法をきめたもの（プロトコル）のことです。
ブラウザは特定のURLにHTTPリクエストを送信し、サーバはHTTPレスポンスを返します。

## 高速化方法
上で紹介したサイトで表示速度を測ると問題点とその対策方法を出してくれるので、基本的にはそれらの対策を一つ一つ実行していくことになります。よくある要因は外部ファイルやコンテンツが重すぎること。基本的に上記で書いた**HTTPリクエストの数を減らすとサイズを減らすの原理** に基づいています。

以下は基本的な対策について。

### 画像を圧縮する
重くなりやすい画像は圧縮しましょう。もちろん劣化がわからない程度に。
有名なパンダなど、圧縮してくれるサービスは色々あるのでお好きなものをどうぞ。
[TinyPNG](https://tinypng.com/)
[Compress JPEG](http://compressjpeg.com/ja/)


### CSSスプライトを使う
複数の画像を一つのシートにして、表示部分をずらすことでそれぞれの絵を見せる方法のことで、画像の枚数分のHTTPリクエストを減らすことができます。
以下のようなサイトで簡単に作れます。
[CSS Sprite Generator](https://spritegen.website-performance.org/)

### インライン画像を使う
URLスキームとしてdata:を利用すればHTTPリクエストを増やさずに文字列化した画像をサイト内に埋め込めます。ただしインライン化で、データサイズが元のサイズより大きくなったりキャッシュされない等のデメリットもあるため、小さな画像にのみ部分的に使用する方が良いかも。
以下のようなサイトで簡単に変換できちゃいます。
[Duri.me - DataURI Generator](http://duri.me/)

### ファイルの結合
CSSやJSのファイルを複数読み込んでいる場合は、できる限り一つにまとめてHTTPリクエストを減らしましょう。

### スタイルシートは先頭に置く
CSSファイルの読み込みタグを先頭に置くことで、ページレイアウトが読み終わったものから随時表示されていくようになりユーザーの体感待ち時間が減ります。ということで、CSSの読み込みはheadタグでしましょう。実際の速度は変わらなくても、実際使うのは人間なので体感時間も大事ですよ。

### スクリプトファイルは最後に置く
逆にJSファイルは先頭に置いちゃダメです。スクリプトを読み込み始めるとレンダリングが止まって、他のコンポーネントの読み込みが止まってしまいます。なのでスクリプトの読み込みはできる限りbodyの閉じタグ前でしましょう。（ものによっては先頭で読むことを推奨しているものもあるので、できる限りということで）

### JSとCSSは外部ファイルにする
JSとCSSをインラインにするとHTTPリクエストが減る分高速になりますが、２回目以降はキャッシュが残るので基本的には外部ファイルにしておいた方がはやくなります。
ユーザーごとのページビューが少なく、キャッシュが空であることが多く、コンポーネントが再利用されないサイト（例えば検索ホームページなど）であればインライン化しても良いかもしれませんね（あんまないと思いますが…）。

### JSの縮小化
不要な文字の除去や空白を無くすことでJSファイルを小さくします。
もう一つ難読化という方法もありますが、バグがでることもあるのでオススメはしません。

### スクリプトの重複を避ける
同じファイルを何度も読み込まないこと。あたりまえだけど、大きなサイトになると何度も同じファイルを読み込んでいることがあります。

### リダイレクトを避ける
リダイレクトとはユーザーをあるURLから他のURLに転送することです。
アクセス回数の記録等で使われるそうですが、これが実行されると遅くなります。
意外に多いのがURLの最後にスラッシュを忘れることによるリダイレクトだそうなので気をつけてみてください。

### キャッシュを設定する
２回目以降の表示で効果を表します。画像やスプライト、スタイルシートに適用可能です。
apacheなら.htaccessファイルでキャッシュの期限を設定しておきましょう（Googleは１週間から１年を推奨）。
ただし、頻繁に更新されるものはキャッシュを指定してしまうと、情報が更新されなくなってしまうことがあるので注意。
ちなみにHTMLはキャッシュを設定しないのが一般的だそうです。

### gzipする
サーバー側での圧縮ですね。
appacheなら.htaccessを修正して圧縮するファイルを設定しましょう。
スクリプトやスタイルシートまで圧縮可能ですが、画像はもう圧縮されているので指定しちゃだめです（サーバーに余計な負担がかかります）。
ただし、サーバー側で圧縮するのでサーバーに負担がかかってしまいサーバーが貧弱だと逆に遅くなる可能性があるので、適用したら実際に速度が早くなっているか確認しましょう。以下のようなサイトで実際に圧縮が有効になっているのか確認できます。

[Gzipチェッカー](https://lab.syncer.jp/Tool/Gzip-Checker/)
[HTTP Compression Test](http://www.whatsmyip.org/http-compression-test/)

### ETagをオフにする
ETagとはキャッシュの有効性を確認する手段の一つだそうです。
ただサーバが複数ある場合などで、期待する動作がおこなわれずパフォーマンスが低下する可能性があるので、使用しない方が良い（そうです）。

### レイジーロードを実装する
サイト内の画像があまりに多くて重いときはレイジーロードで画像を読み込むタイミングを送らせてしまいます。
今後サイトを作り変える可能性がある場合はめんどくさくなりますが、画像の多いサイトだとかなりの威力を発揮します。

こんな感じですね。
自分のサイトが遅いと感じたらぜひ対策をとってみてください。