ざっくりWEBサイト高速化

プログラミング学習サービスやら、ペットサロン予約サービス、風俗検索サービスなど色々とやっている「かずきち」です。
■運営サービス一部
http://crazy-wp.com/
http://webukatu.com/
新宿のホストから不動産・保険の営業を経て、HTMLって何？という状態から３ヶ月独学でプログラミングやデザインを学び、IT業界で１年間実務経験を積んで年収は１本超え。現在は起業家としてサービス運営やら不動産運営をしています。
Qiita内にそれ系の記事も書いてます。
<a href="http://qiita.com/kazukichi/items/7379b75fba2f90d3cf45" target="_blank">エンジニアで稼ぐために大切な１３のコト</a>
<a href="http://qiita.com/kazukichi/items/aeba286c2a750081e5c0" target="_blank">WEBサービスで起業したい人に読んで欲しい１８のコト</a>

#WEBの仕組み
高速化を考える上では、まずWEBを表示する仕組みを理解し、それぞれの部分に分けて考える必要がある。
WEBを表示する仕組みは単純にすると「ブラウザ」「WEBサーバー」「DB（データベース）」があり、その間で通信が行われ、ファイルの送受信がされることでブラウザに表示されている。

```text
■イメージ図

ブラウザ　⇔　WEBサーバー　⇔　DB

■WEBが表示されるまでの流れイメージ

ブラウザがWEBサーバーへファイルを要求　→　WEBサーバー内でプログラムが動く　→　プログラム内で必要な情報をDBへ検索する　→　DBは情報を検索して返す　→　WEBサーバーはプログラム実行後、ファイルを返す　→　ブラウザはファイルを受け取りレンダリング（描画）する　→　ブラウザにページが表示される

```

高速化にはまず大きくわけて２つある。

1. ハード面の高速化　→　サーバーを複数台使う、高速なサーバーを使う、CDNを使うなど
2. ソフト面の高速化　→　これから紹介するもの

さらにソフト面での高速化には大きく分けて３つある。

1. 通信頻度を抑える　→　サーバーやDBへの問い合わせ頻度を減らす
2. 通信量を抑える　　→　一回の問い合わせで通信される量を減らす
3. 実行速度を上げる　→　コード量を減らしたり書き方を工夫するなど（通信量を減らす事にも繋がる場合あり）

#高速化その１：通信頻度を減らす方法

## HTTPリクエストを減らす
htmlをサーバーへリクエストし、返ってきたhtmlファイルをブラウザが読み込むが、
そのhtmlファイル内に外部cssやimgなどファイルがある場合は、その度にサーバーへリクエストを投げている。
その分、通信が発生し時間がかかっている。
### ■方法１：CSSスプライトを使う
使う画像を１つの画像ファイルにまとめてCSSで使う画像の場所を指定する方法。
画像リクエスト数を減らせる。

### ■方法２：jsやCSSファイルを一つにする
SASSなどを使って、ファイルは複数で管理し、吐き出すときには一つのファイルにする。
ファイルリクエスト数を減らせる。

### ■方法３：キャッシュを使う

#### Expiresヘッダーを追加する
Expiresヘッダーはサーバーへ新しいファイルが存在するか確認せずにブラウザ側で強制的にキャッシュ済みのファイルを使うもの。
キャッシュ済みのファイルを強制的に読み込む期間を指定することで、この期間は強制的にコンピュータ内に保存されたキャッシュファイルを読み込むことになる。
期限は１年以上にしないこと。（RFCガイドラインに反するので）
強制キャッシュなので、更新の多いページにはなるべく使わないこと。
ファイル名が変わればキャッシュは効かないため、ファイル名は使い捨てにするといい。
（ファイル名にバージョンをつけておくといい）

#### Expiresヘッダーの編集は.htaccessで行う

```text:例
# BEGIN Browser Cache
<ifModule mod_expires.c>
　ExpiresActive On
　ExpiresByType image/png "access plus 1 months"
　ExpiresByType image/jpeg "access plus 1 months"
　ExpiresByType image/gif "access plus 1 months"
　ExpiresByType text/css "access plus 1 months"
</ifModule>
# END Browser Cache
```

###jsとCSSを外部ファイル化する
外部ファイル化することで、jsやcssファイルをキャッシュできる。
キャッシュできることで、次のhtmlファイルを読み込んだ際にhtmlだけを読みこめばいいことになる。

実際、JavaScriptとCSSファイルは、ブラウザにキャッシュされるので外部ファイルにした方が、ページ表示は速くなるのが普通。HTML中のインラインのJavaScriptとCSSは、HTMLがリクエストされる毎にダウンロードされます。確かにHTTPリクエストの数は減るが、HTMLのサイズは大きくなる。他方、JavaScriptとCSSを外部ファイルとした場合は、ブラウザキャッシュされていれば、HTTPリクエストの数は減らないが、HTMLのサイズを大幅に小さくする。

主なファクターは、JavaScriptとCSSのキャッシュがどれくらい有効かということになる。定量化するのが難しいが、様々な手法を使用することでこの要素を測定することができる。ユーザの1セッションあたりのページ・ビューと、ページ横断でのスクリプトとスタイルシートの再利用率によっては、外部ファイルがキャッシュ可能であるという点で大きなメリットになる。

ほとんどのwebサイトは測定上、中くらいの位置になる。そのようなサイトのベストな解決はJavaScriptとCSSを外部ファイルとすること。
ただし、Yahoo! ([http://www.yahoo.com](http://www.yahoo.com))やMy Yahoo! ([http://my.yahoo.com](http://my.yahoo.com))のトップページのように例外的にインラインで埋め込んだほうが良い場合はある。セッションあたりのページビューが少ないトップページは、インラインで埋め込んだほうが良い場合もある。

たくさんのページビューの最初となるトップページでは、インラインによってHTTPリクエストの数を減らしながら、外部ファイルによるキャッシュ効果も得るテクニックがある。

トップページではJavaScriptとCSSをインラインで使用して、ページがロードし終わったら、動的に外部ファイルをロードする。そうすれば、次のページではブラウザキャッシュ上の外部ファイルを利用できる。

##リダイレクトを避ける

`http://astrology.yahoo.com/astrology/`と書くべきところを
`http://astrology.yahoo.com/astrology`と書いてしまうと（最後の”/”を忘れている）、
`http://astrology.yahoo.com/astrology/`に301レスポンスで飛ばされる。

そうるすると２回通信していることになるため、無駄。
リンクなどでのURLの記述の最後には必ず/をつけること。

#高速化その２：通信量を減らす

##コンポーネントを圧縮する
ファイルサイズを小さくすることで、サーバーからのレスポンスを速くできる。
テキストファイルは圧縮すべきだが、画像やpdfは圧縮すると逆にCPUを浪費するので注意。

##画像ファイルを圧縮する
色々なファイルの中でも画像が一番ファイルサイズが大きい。
この画像を圧縮するだけでかなりの通信量を減らすことが出来る。
gulpのimage-minや各種圧縮ソフトなどで画像を圧縮してサーバーに配置する。

##コードのサイズを圧縮する
いわゆる「Minify（ミニファイ）」というやつ。
「難読化」と「圧縮」があるが、難読化はバグが生まれる可能性があるためやらない方がいい。
空白や改行を除いたり、ソース内のコメントをなくしたりなどの「圧縮」は効果あり。


#高速化その３：実行速度を上げる


##CSSはheadタグ内に書く
CSSが全部読み込まれるまでレンダリングされないため、早めに読み込まないと真っ白な画面が続くことになる。
また、ユーザビリティ的にも「今読み込んでいる」というのが分かるように上から順にレンダリングされていっているのが見える方がいい。

##scriptはbody閉じタグ前に書く
jsをダウンロードしている間は並列読込みできない。
そのため、順にファイルを読み込んでいくしかなく、読込み速度が遅くなるため、htmlの最後で読み込むようにする。

##CSSセレクタの解析時間を短くする
CSSセレクタは右から左へ読み込まれ、解析される。
例えば、


```css:CSS
.panel a
```

なら、html内のa要素を全て解析し、その後にclass属性がpanelのものを解析するので解析時間がかなりかかってしまう。

###画像の読込みを待たずにレンダリングする
imgタグにはwidthとheightを指定する。