.htaccess の書き方（スピードアップ編）

1. [.htaccess の書き方（リダイレクト編）](http://qiita.com/shotets/items/1f8f308e008dcb96bf43)
2. [.htaccess の書き方（アクセス制御編）](http://qiita.com/shotets/items/17bed9029140a6d925d2)
3. [.htaccess(Apache) の Order Allow,Deny(またはDeny,Allow)について](http://qiita.com/shotets/items/58a69aa15e2adc9f930a)
4. **.htaccess の書き方（スピードアップ編）**
5. [.htaccess の書き方（設定変更編）](http://qiita.com/shotets/items/cf0783530a1f2809c4d5)


Webサイトの表示速度を上げることはアクセス数アップにつながる。昔から人は３秒で判断すると言われており、実際に速度が原因で半数以上が離脱するというデータもある。３秒以内だから安心というわけではなく、速ければ速いほどユーザーの滞在時間は長くなるという調査結果がある。

* Amazon：100ms 遅くなると売上が 1％ 低下した。
* Google：読み込み時間が 500ms 遅くなることで、検索件数が 20％ 減少した。
* Yahoo!：読み込み時間が 400ms 遅くなることで、ページが読み込まれる前に「戻る」をクリックした人の数が 5～9％ 増加した。

また、表示スピードは SEO にも影響を与えるため、速度改善は検索エンジンからの集客にも効果がある。表示速度の改善は価値のある対策と言える。ここでは .htaccess でできる範囲の速度改善について記述する。


## 圧縮で表示速度を上げる（かもしれない）

[mod_deflate](https://httpd.apache.org/docs/2.4/ja/mod/mod_deflate.html) ：htmlやcssなどをサーバー上で圧縮し、クライアント側に送信するデーター量を減らす。
[mod_pagespeed](https://developers.google.com/speed/pagespeed/module/) ：Google製の拡張モジュールで、画像のキャッシュやファイルの圧縮により、クライアント側に送信するデーター量を減らす。

どちらもサーバー側で圧縮するのでサーバーに負荷がかかり、サーバーが貧弱だと逆に遅くなる可能性があります。実装してから速度が上がっているかどうか、必ず確認するようにしてください。


### mod_deflate による圧縮

画像ファイルとPDFファイルはすでに圧縮されているので、画像を圧縮対象にするとCPUが浪費されます。対象にしないでください。

```apache:.htaccess
<ifModule mod_deflate.c>
<IfModule mod_filter.c>
AddOutputFilterByType DEFLATE text/html text/xml text/css text/plain
AddOutputFilterByType DEFLATE image/svg+xml application/xhtml+xml application/xml
AddOutputFilterByType DEFLATE application/rdf+xml application/rss+xml application/atom+xml
AddOutputFilterByType DEFLATE text/javascript application/javascript application/x-javascript application/json
AddOutputFilterByType DEFLATE application/x-httpd-php application/x-httpd-fastphp
AddOutputFilterByType DEFLATE application/x-font-ttf application/x-font-otf
AddOutputFilterByType DEFLATE font/truetype font/opentype
</IfModule>
</ifModule>
```

※ Apache のバージョンが 2.3.7 より下の場合は `AddOutputFilterByType` がまだコアディレクティブにあるので `<IfModule mod_filter.c>` は必要ありません。


### mod_pagespeed による圧縮

mod_pagespeed はモジュールのインストールが必要なので、モジュールが入っていない共有サーバーでは使えません。使える共有サーバー（Xserver等）を使うか、root 権限が使える VPS 等でモジュールをインストールしてお試しください。

```apache:.htaccess
<IfModule pagespeed_module>
ModPagespeed on
# 画像劣化が気になる場合は画像圧縮をOFFに
ModPagespeedDisableFilters rewrite_images
</IfModule>
```


## ブラウザキャッシュを活用する

パソコンや端末の性能が向上し、できることが増えるとついついWebサイトの容量が増えてしまう。CSSやjsファイル、favicon、画像、Webフォント等、更新頻度が低くて容量が大きいものはブラウザにキャッシュさせれば、別のページに移動した際や再訪問した際に読み込むファイル数を減らすことができる。サーバーへのリクエストも減るためサーバー負荷も抑えられる。

### Expires ヘッダー

Expires ヘッダーは指定された期間は最新ファイルかどうかすらもサーバーに問合せずに強制的にブラウザのキャッシュを適用させます。優先度の高いキャッシュ機能で、サーバーに問合せすらしないのでサーバーにログも残りません。ファイル名を変更してのキャッシュ無効化でバージョン管理を制御しない場合や更新頻度が高い場合、動的コンテンツ、リニューアル時期が近い場合などはキャッシュ時間を短くするか、Expires ヘッダーを指定しないようにしましょう。

```apache:.htaccess
<IfModule mod_expires.c>

    ExpiresActive on
    ExpiresDefault                                      "access plus 1 month"

    # CSS
    ExpiresByType text/css                              "access plus 1 year"

    # RSS
    ExpiresByType application/atom+xml                  "access plus 1 hour"
    ExpiresByType application/rdf+xml                   "access plus 1 hour"
    ExpiresByType application/rss+xml                   "access plus 1 hour"

    # データはキャッシュさせない
    ExpiresByType application/json                      "access plus 0 seconds"
    ExpiresByType application/ld+json                   "access plus 0 seconds"
    ExpiresByType application/schema+json               "access plus 0 seconds"
    ExpiresByType application/vnd.geo+json              "access plus 0 seconds"
    ExpiresByType application/xml                       "access plus 0 seconds"
    ExpiresByType text/xml                              "access plus 0 seconds"

    # Favicon
    ExpiresByType image/vnd.microsoft.icon              "access plus 1 week"
    ExpiresByType image/x-icon                          "access plus 1 week"

    # HTML
    ExpiresByType text/html                             "access plus 0 seconds"

    # JavaScript
    ExpiresByType application/javascript                "access plus 1 year"
    ExpiresByType application/x-javascript              "access plus 1 year"
    ExpiresByType text/javascript                       "access plus 1 year"

    # マニフェスト
    ExpiresByType application/manifest+json             "access plus 1 week"
    ExpiresByType application/x-web-app-manifest+json   "access plus 0 seconds"
    ExpiresByType text/cache-manifest                   "access plus 0 seconds"

    # 画像や動画
    ExpiresByType audio/ogg                             "access plus 1 month"
    ExpiresByType image/bmp                             "access plus 1 month"
    ExpiresByType image/gif                             "access plus 1 month"
    ExpiresByType image/jpeg                            "access plus 1 month"
    ExpiresByType image/png                             "access plus 1 month"
    ExpiresByType image/svg+xml                         "access plus 1 month"
    ExpiresByType image/webp                            "access plus 1 month"
    ExpiresByType video/mp4                             "access plus 1 month"
    ExpiresByType video/ogg                             "access plus 1 month"
    ExpiresByType video/webm                            "access plus 1 month"

    # Webフォント
    
    # Embedded OpenType (EOT)
    ExpiresByType application/vnd.ms-fontobject         "access plus 1 month"
    ExpiresByType font/eot                              "access plus 1 month"

    # OpenType
    ExpiresByType font/opentype                         "access plus 1 month"

    # TrueType
    ExpiresByType application/x-font-ttf                "access plus 1 month"

    # Web Open Font Format (WOFF) 1.0
    ExpiresByType application/font-woff                 "access plus 1 month"
    ExpiresByType application/x-font-woff               "access plus 1 month"
    ExpiresByType font/woff                             "access plus 1 month"

    # Web Open Font Format (WOFF) 2.0
    ExpiresByType application/font-woff2                "access plus 1 month"

    # Other
    ExpiresByType text/x-cross-domain-policy            "access plus 1 week"

</IfModule>
```



### Cache-Controlヘッダー

mod_expires モジュールを設定している場合は Cache-Control ヘッダーで max-age ディレクティブを設定する必要はありません。Expires と Cache-Control: max-age の両方を指定すると冗長になります。

```apache:.htaccess
# mod_headersが必要
<ifModule mod_headers.c>
  <filesMatch "\.(ico|jpe?g|png|gif|swf)$">
    Header set Cache-Control "public"
  </filesMatch>
  <filesMatch "\.(css)$">
    Header set Cache-Control "public"
  </filesMatch>
  <filesMatch "\.(js)$">
    Header set Cache-Control "private"
  </filesMatch>
  <filesMatch "\.(x?html?|php)$">
    Header set Cache-Control "private, must-revalidate"
  </filesMatch>
</ifModule>
```

<dl>
<dt>public</dt>
<dd>全てのユーザーに共通のキャッシュ。</dd>
<dt>private</dt>
<dd>特定のユーザーのためのキャッシュ。特定ユーザーの個人情報が含まれるページなどに使う。</dd>
<dt>no-store</dt>
<dd>キャッシュしない。</dd>
<dt>no-cache</dt>
<dd>キャッシュしたものが今でも更新されずに有効かどうかが確認できなければそのキャッシュは使うなという意味。名前から勘違いしやすいが、キャッシュしないという意味ではない。</dd>
<dt>must-revalidate</dt>
<dd>キャッシュに記録されているコンテンツが現在も有効であるか否かをWebサーバに必ず問い合わせよという指示。</dd>
</dl>

参考
https://www.ipa.go.jp/security/awareness/vendor/programmingv2/contents/405.html


### ETag をオフにする

最終更新日よりも柔軟性のあるエンティティを検証するためのメカニズムを提供するために ETags が追加されました。しかし、ETags には問題があります。複数マシンで構成しているサーバーだと、同じデータでもデータ配信サーバーが異なると ETag は一致しません。

また、ETag が有効だとサーバー側は毎回実ファイルを調べて ETag 情報を生成し、比較することになるので更新頻度が低いファイルでは余計な処理となります。Expires と組み合わせて無効にする方が良いです。

```apache:.htaccess
<ifModule mod_headers.c>
    Header unset ETag
</ifModule>
FileETag None
```