ChromeのヘッドレスモードをMacOSXで試してみた

マストドンで盛り上がる最中、
こっそり一部で盛り上がってた[Chromeのヘッドレスモード](https://www.chromestatus.com/features/5678767817097216)
MacOSXで少し試してみたいと思います。

開発中の機能ということで、仕様の変更もあると思いますが、2017/4/16段階ではちゃんと以下のやり方で動作してます:)

## 準備
[Google Chrome Canary](https://www.google.com/chrome/browser/canary.html)をインストール
開発段階にある機能がのってるchromeです。ささっと入れちゃいます。

nodejsインストール(v6.3以上)
ちなみに今回試したのはv7.9.0

シェルにCanaryバイナリへのエイリアスを作成します(僕は.zshrcに追加しました/bashの人は.bash_profileかな)

```
alias chrome-c='/Applications/Google\ Chrome\ Canary.app/Contents/MacOS/Google\ Chrome\ Canary'
```

設定を読み込みます(source ~/.zshrc)

適当なディレクトリを作成して、その中にscript.jsを作成します。

```
$mkdir headless-test
$npm install chrome-remote-interface
$vim script.js
```

```js:script.jsの中身
const CDP = require('chrome-remote-interface');

CDP((client) => {
  // Extract used DevTools domains.
  const {Page, Runtime} = client;

  // Enable events on domains we are interested in.
  Promise.all([
    Page.enable()
  ]).then(() => {
    return Page.navigate({url: 'https://example.com'});
  });

  // Evaluate outerHTML after page has loaded.
  Page.loadEventFired(() => {
    Runtime.evaluate({expression: 'document.body.outerHTML'}).then((result) => {
      console.log(result.result.value);
      client.close();
    });
  });
}).on('error', (err) => {
  console.error('Cannot connect to browser:', err);
});
// [引用](https://github.com/cyrus-and/chrome-remote-interface)
```

## 実行してみる

ターミナルを2画面開いて
一つで先に

```
$ chrome-c --headless --remote-debugging-port=9222 https://chromium.org
特に出力はなく、入力待ちみたいな状態になります
もしmesa library周りのエラーが出たら--disable-gpuオプションをつけると良いそうです。
```

もう一つで

```
$node script.js
スクリプト内のhttps://example.comをアクセスしたいurlに変更してください
以下はqiita.comへアクセスした際の出力
https://qiita.com/
https://cdn.qiita.com/assets/public-f33264c77b8d85793c9875b153a1a98b.min.css
https://cdn.qiita.com/assets/siteid-large-c5f1d2812cc28cb0621d57061b9eb0f5.png
https://www.google.com/recaptcha/api.js
https://b.hatena.ne.jp/images/entry-button/button-only.gif
https://b.hatena.ne.jp/js/bookmark_button.js
...
```

読み込みされてるようです!
以上!!

## おまけ

### Nginxで確認したアクセスログ

自サイトへリクエストを送ってログをチェックしてみました

```
[16/Apr/2017:14:30:04 +0900] "GET / HTTP/1.1" 200 2783 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_4) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/60.0.3072.0 Safari/537.36" "-"
```

HeadlessChromeってなってます!

### ページロードの計測
script.jsを以下のように変更してみました。

```js
const CDP = require('chrome-remote-interface');

CDP((client) => {
    // extract domains
    const {Network, Page} = client;
    // setup handlers
    Network.requestWillBeSent((params) => {
        console.log(params.request.url);
    });
    Page.loadEventFired(() => {
        client.close();
        console.timeEnd('loadtimer')
        console.log('timer-end')
    });
    // enable events then start!
    Promise.all([
        Network.enable(),
        Page.enable()
    ]).then(() => {
        console.log('timer-start')
        console.time('loadtimer')
        var res = Page.navigate({url: 'https://qiita.com'});
        return res;
    }).catch((err) => {
        console.error(err);
        client.close();
    });
}).on('error', (err) => {
    // cannot connect to the remote endpoint
    console.error(err);
});
```

実行した結果

```
// 実行結果
timer-start
https://qiita.com/
https://cdn.qiita.com/assets/public-f33264c77b8d85793c9875b153a1a98b.min.css
https://cdn.qiita.com/assets/siteid-large-c5f1d2812cc28cb0621d57061b9eb0f5.png
https://www.google.com/recaptcha/api.js
https://b.hatena.ne.jp/images/entry-button/button-only.gif
https://b.hatena.ne.jp/js/bookmark_button.js
https://platform.twitter.com/widgets.js
...

loadtimer: 1260.686ms
timer-end
```

qiitaトップは、1sくらいでページ読み込みができるみたいです(これでちゃんと計測できてるのかな?)

## 参考

https://chromium.googlesource.com/chromium/src/+/lkgr/headless/README.md
https://github.com/cyrus-and/chrome-remote-interface