ページ表示速度の問題チェックをしてくれるgrunt-pagespeedについて紹介するよ

# grunt-pagespeedとは
Gruntで指定ページをPageSpeed InsightsでチェックしてくれるGruntプラグインです。

https://npmjs.org/package/grunt-pagespeed
https://github.com/jrcryer/grunt-pagespeed

# PageSpeed Insightsとは
> PageSpeed Insightsは、ウェブページのコンテンツを解析し、ページの読み込み時間を短くするための方法を提案します。

とPageSpeed Insightsのサイトに説明があるように、ページのパフォーマンス的に改善できるポイントを見つけて「こうしたらもっと良くなるよ」という改善案まで提示してくれる、素晴らしいサービスです。
Webサービスとしても提供されていますし、ブラウザの拡張機能としても提供されています。

PageSpeed Insights
https://developers.google.com/speed/pagespeed/insights/

PageSpeed Insights Chrome拡張
https://chrome.google.com/webstore/detail/pagespeed-insights-by-goo/gplegfbjlmmehdoakndmohflojccocli

![pagespeedinsights.png](https://qiita-image-store.s3.amazonaws.com/0/1137/aa303d7a-0f52-d4b7-c305-3b8196a143b0.png)

# 導入
## インストール
npm installでgrunt-pagespeedをインストールします。package.jsonのdevDependenciesに追加されるように--save-devオプションを忘れずに。

```
% npm install grunt-pagespeed--save-dev
```

## Gruntfile.js
`grunt-pagespeed` タスクをロードするように追記し、pegespeedタスクを定義します。
ここではPageSpeedのデスクトップ版チェック、モバイル版チェックを定義しています。

```
module.exports = function(grunt) {
  grunt.initConfig({
    pagespeed: {
      desktop: {
        options: {
          paths: ['/', '/bijin-zoroe/', '/bijin/1134'],
          locale: 'ja_JP',
          strategy: 'desktop',
          threshold: 70
        }
      },
      mobile: {
        options: {
          locale: 'ja_JP',
          strategy: 'mobile',
          threshold: 65
        }
      },
      options: {
        key: 'API_KEY',
        url: 'http://bihyaku.appspot.com'
      }
    }
  });
  grunt.loadNpmTasks('grunt-pagespeed');
}; 
``` 

### オプションの重要部分の説明
* paths: urlで指定されたチェック対象ページでチェックを行うパスを列挙する
* locale: ロケールを指定する
* strategy: 
 * desktop: デスクトップからのアクセスを想定してのPageSpeedチェックを実行する
 * mobile:  スマートフォンのようなモバイルからのアクセスを想定してのPageSpeedチェックを実行する
* threshold: PageSpeedチェックのスコアのしきい値を指定する(上限100)。これ未満の場合はエラーになります。
* key: PageSpeed APIのAPIキー文字列
* url: チェック対象ページのURL

## Google APIキーの取得
Google Cloud Consoleからプロジェクトの作成、アプリの登録を行い、APIキーを取得します。
https://cloud.google.com/console

# 実行
`grunt pagespeed`でPageSpeed Insightsチェックを実行すると下記のように各チェック項目ごとに数値化されて、結果が出力されます。
なお、下記の例ではモバイル側のチェックでのスコアが指定されたthreshold未満なので、エラーになっています。

```
% grunt pagespeed
Running "pagespeed:desktop" (pagespeed) task
>>
>> ----------------------------------------------------------------
>>
>> URL:   http://bihyaku.appspot.com/bijin-zoroe/
>> Score: 81
>>
>> ----------------------------------------------------------------
>>
>> Number  Resources                                | 21
>> Number  Hosts                                    | 4
>> Total  Request  Bytes                            | 1526
>> Number  Static  Resources                        | 18
>> Html  Response  Bytes                            | 16052
>> Css  Response  Bytes                             | 5679
>> Image  Response  Bytes                           | 646156
>> Javascript  Response  Bytes                      | 149340
>> Number  Js  Resources                            | 6
>> Number  Css  Resources                           | 2
>>
>> ----------------------------------------------------------------
>>
>> Avoid  Landing  Page  Redirects                  | 0
>> Enable  Gzip  Compression                        | 0.49
>> Leverage  Browser  Caching                       | 8
>> Main  Resource  Server  Response  Time           | 1.65
>> Minify  Css                                      | 0
>> Minify HTML                                      | 0
>> Minify  Java  Script                             | 0.46
>> Minimize  Render  Blocking  Resources            | 8
>> Optimize  Images                                 | 2.83
>> Prioritize  Visible  Content                     | 2
>>
>> ----------------------------------------------------------------
>>
>>
>> ----------------------------------------------------------------
>>
>> URL:   http://bihyaku.appspot.com/
>> Score: 77
>>
>> ----------------------------------------------------------------
>>
>> Number  Resources                                | 48
>> Number  Hosts                                    | 10
>> Total  Request  Bytes                            | 3019
>> Number  Static  Resources                        | 45
>> Html  Response  Bytes                            | 9454
>> Css  Response  Bytes                             | 80510
>> Image  Response  Bytes                           | 1170466
>> Javascript  Response  Bytes                      | 213486
>> Number  Js  Resources                            | 5
>> Number  Css  Resources                           | 3
>>
>> ----------------------------------------------------------------
>>
>> Avoid  Landing  Page  Redirects                  | 0
>> Enable  Gzip  Compression                        | 0.61
>> Leverage  Browser  Caching                       | 13
>> Main  Resource  Server  Response  Time           | 0.75
>> Minify  Css                                      | 0.08
>> Minify HTML                                      | 0
>> Minify  Java  Script                             | 0
>> Minimize  Render  Blocking  Resources            | 8
>> Optimize  Images                                 | 6.55
>> Prioritize  Visible  Content                     | 2
>>
>> ----------------------------------------------------------------
>>
>>
>> ----------------------------------------------------------------
>>
>> URL:   http://bihyaku.appspot.com/bijin/1134
>> Score: 66
>>
>> ----------------------------------------------------------------
>>
>> Number  Resources                                | 38
>> Number  Hosts                                    | 11
>> Total  Request  Bytes                            | 2479
>> Number  Static  Resources                        | 35
>> Html  Response  Bytes                            | 9360
>> Css  Response  Bytes                             | 80512
>> Image  Response  Bytes                           | 4856865
>> Javascript  Response  Bytes                      | 213560
>> Number  Js  Resources                            | 5
>> Number  Css  Resources                           | 3
>>
>> ----------------------------------------------------------------
>>
>> Avoid  Landing  Page  Redirects                  | 0
>> Enable  Gzip  Compression                        | 0.67
>> Leverage  Browser  Caching                       | 13
>> Main  Resource  Server  Response  Time           | 0.73
>> Minify  Css                                      | 0.08
>> Minify HTML                                      | 0
>> Minify  Java  Script                             | 0
>> Minimize  Render  Blocking  Resources            | 8
>> Optimize  Images                                 | 30.55
>> Prioritize  Visible  Content                     | 2
>>
>> ----------------------------------------------------------------
>>
Fatal error: Threshold of 70 not met with score of 66
```

# まとめ
ブラウザ上からではなく、GruntからPageSpeed Insightsチェックが実行できることがわかっていただけたと思います。
release用のタスクの後、またはJenkinsなどのCIツールから実行して、パフォーマンス劣化していないか`grunt pagespeed`でチェックしてみてください。

# Tips
PageSpeed APIのAPIキーはアカウントに紐づくものなので、Gitリポジトリで管理共有はしたくないという場合はGruntfile.jsから外出ししてしまいましょう。
例えば、下記のように`.env.conf.json`のようなAPIキー情報を記載したファイルを作成し、チームメンバーとは共有しないように`.gitignore`に指定しておきます。あとは`Gruntfile.js`内では`.env.conf.json`をrequireし、optionsの`key`からはrequireで代入された`env`変数を参照するといったことも可能です。

```.env.conf.json
{
    'pagespeed': {
        'key': 'REPLACE WITH YOUR GOOGLE API KEY'
    }
}
```

```.gitignore
.env.conf.json
```

```Gruntfile.js
module.exports = function(grunt) {
  grunt.initConfig({
    env: require('.env.conf.json’)
(略)
    pagespeed: {
(略)
      options: {
        key: '<%= env.pagespeed.key %>',
        url: 'http://bihyaku.appspot.com'
      }
    }
  });
  grunt.loadNpmTasks('grunt-pagespeed');
};  
``` 

#Appendix
Grunt Plugins
http://gruntjs.com/plugins