1. wokamoto

    No comment

    wokamoto
Changes in body
Source | HTML | Preview
@@ -1,131 +1,131 @@
先日リリースされた Nginx ver.1.13.9 に [http2_push](http://nginx.org/en/docs/http/ngx_http_v2_module.html#http2_push) と [http2_push_preload](http://nginx.org/en/docs/http/ngx_http_v2_module.html#http2_push_preload) ディレクティブが実装されました。
> Changes with nginx 1.13.9 20 Feb 2018
>
> *) Feature: HTTP/2 server push support; the "http2_push" and
> "http2_push_preload" directives.
>
> *) Bugfix: "header already sent" alerts might appear in logs when using
> cache; the bug had appeared in 1.9.13.
>
> *) Bugfix: a segmentation fault might occur in a worker process if the
> "ssl_verify_client" directive was used and no SSL certificate was
> specified in a virtual server.
>
> *) Bugfix: in the ngx_http_v2_module.
>
> *) Bugfix: in the ngx_http_dav_module.
そんなわけで、WordPress が読み込んでるスタイルシートやら、JavaScript やらを HTTP/2 Push してみようという試み。
<img width="956" alt="スクリーンショット 2018-02-23 10.48.01.png" src="https://qiita-image-store.s3.amazonaws.com/0/25964/68e41c5e-418e-a723-56a2-959f325d8ca3.png">
AMIMOTO AMI を使ってる方は、以下のコマンドで Nginx をバージョンアップしておいてください。
```bash
$ sudo /opt/local/provision
```
## Nginx 側の設定変更
`http2_push` ディレクティブを使う場合は、 `server` セクション、もしくは `location` セクションに プッシュしたいファイルを列挙していけばいいです。
```conf
server {
:
http2_push /wp-content/themes/twentyseventeen/style.css?ver=4.9.4;
:
}
```
でも、WordPress 使ってるとテーマ変更したり、プラグイン追加しただけで push したい css や js が変わってきますよね。
それに合わせて一々 nginx.conf 書き換えるだなんて正気の沙汰じゃないです。
ここは `http2_push_preload` ディレクティブを使っていきましょう。
`http2_push_preload` ディレクティブが `on` になっていると(デフォルトは off です)、アプリケーションが送出する `Link` ヘッダを解釈して勝手に HTTP/2 push してくれます。
なので nginx.conf では、以下のように `server` セクションに `http2_push_preload on;` を追加しておくだけです。
```conf
server {
:
http2_push_preload on;
:
}
```
## WordPress で Link ヘッダをだす。
次は、お作法に従って WordPress から適切な `Link` ヘッダを出してあげればいいです。
ちなみに最初のスクリーンショットにあるサイトは以下のような `Link` ヘッダを出してます。
```text
Link: </wp-content/plugins/amazon-polly/public/css/amazonpolly-public.css?ver=1.0.0>; rel=preload; as=style, </wp-content/themes/twentyseventeen/style.css?ver=4.9.4>; rel=preload; as=style
Link: </wp-content/plugins/amazon-polly/public/js/amazonpolly-public.js?ver=1.0.0>; rel=preload; as=script, </wp-content/themes/twentyseventeen/assets/js/skip-link-focus-fix.js?ver=1.0>; rel=preload; as=script, </wp-content/themes/twentyseventeen/assets/js/global.js?ver=1.0>; rel=preload; as=script, </wp-content/themes/twentyseventeen/assets/js/jquery.scrollTo.js?ver=2.1.2>; rel=preload; as=script
```
`Link` ヘッダの出し方は以下を参考にしてください。
[Preload > Server Push (HTTP/2)](http://nginx.org/en/docs/http/ngx_http_v2_module.html#http2_push)
HTTP/2 push したいときは、こんな感じで `Link` ヘッダを出せって言ってますね。
```text
Link: </app/style.css>; rel=preload; as=style; nopush
Link: </app/script.js>; rel=preload; as=script
```
複数のファイルをプッシュしたいときは、カンマ区切りでも良いとも言ってますね。
```text
Link: </app/style.css>; rel=preload; as=style, </app/script.js>; rel=preload; as=script
```
さて、WordPress では css や js は [wp_enqueue_style()](https://developer.wordpress.org/reference/functions/wp_enqueue_style/), [wp_enqueue_script()](https://developer.wordpress.org/reference/functions/wp_enqueue_script/) で登録するのがお作法です。
真っ当なテーマやプラグインなら、これで登録してるはずなので、この情報を使って Link ヘッダを出してみましょう。
以下のようなプラグインを作って有効にすればオッケーかと思われます。
```php:http2_push.php
<?php
/*
Plugin Name: HTTP/2 Push
Plugin URI:
Description: HTTP/2 Push
Author: wokamoto
Version: 0.0.1
Author URI: http://dogmap.jp/
License:
Released under the GPL license
http://www.gnu.org/copyleft/gpl.html
*/
add_action('template_redirect', function(){
if ( headers_sent() ) {
return;
}
do_action('wp_enqueue_scripts');
foreach( array('style' => wp_styles(), 'script' => wp_scripts()) as $as => $wp_links ) {
$link = '';
foreach ( $wp_links->queue as $handle ) {
if ( $wp_links->registered[$handle] && ! preg_match('/-ie8$/i',$handle) && 'html5' !== $handle ) {
$wp_link = $wp_links->registered[$handle];
$src = preg_replace('#^https?://[^/]+#', '', $wp_link->src);
$ver = $wp_link->ver ? $wp_link->ver : $wp_links->default_version;
$link .= !empty($link) ? ', ' : '';
$link .= " <{$src}?ver={$ver}>; rel=preload; as={$as}";
//header("Link: <{$src}?ver={$ver}>; rel=preload; as={$as}", false);
}
}
if ( !empty($link) ) {
- header("Link:$link", false);
+ header("Link:{$link}", false);
}
}
}, 0, 1);
```
このプラグインの解説は割愛。enqueue されてる css や js を拾ってきて、よしなに `Link` ヘッダを作ってくれるプラグインです。
なお、このプラグインと Nginx 1.13.9 で HTTP/2 push を有効にしたサイトは以下になります。
https://lets.ninja/
Let's Ninja !