10
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

[WordPress][Nginx] Nginx 1.13.9 に実装された http2_push_preload を使って HTTP/2 push してみる

Last updated at Posted at 2018-02-23

先日リリースされた Nginx ver.1.13.9 に http2_pushhttp2_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 してみようという試み。
スクリーンショット 2018-02-23 10.48.01.png

AMIMOTO AMI を使ってる方は、以下のコマンドで Nginx をバージョンアップしておいてください。

$ sudo /opt/local/provision
$ nginx -v
nginx version: nginx/1.13.9

Nginx 側の設定変更

http2_push ディレクティブを使う場合は、 server セクション、もしくは location セクションに プッシュしたいファイルを列挙していけばいいです。

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; を追加しておくだけです。

server {
  :
    http2_push_preload on;
  :
}

WordPress で Link ヘッダをだす。

次は、お作法に従って WordPress から適切な Link ヘッダを出してあげればいいです。
ちなみに最初のスクリーンショットにあるサイトは以下のような Link ヘッダを出してます。

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/2 push したいときは、こんな感じで Link ヘッダを出せって言ってますね。

Link: </app/style.css>; rel=preload; as=style; nopush
Link: </app/script.js>; rel=preload; as=script

複数のファイルをプッシュしたいときは、カンマ区切りでも良いとも言ってますね。

Link: </app/style.css>; rel=preload; as=style, </app/script.js>; rel=preload; as=script

さて、WordPress では css や js は wp_enqueue_style(), wp_enqueue_script() で登録するのがお作法です。
真っ当なテーマやプラグインなら、これで登録してるはずなので、この情報を使って Link ヘッダを出してみましょう。
以下のようなプラグインを作って有効にすればオッケーかと思われます。

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);
        }
    }

}, 0, 1);

このプラグインの解説は割愛。enqueue されてる css や js を拾ってきて、よしなに Link ヘッダを作ってくれるプラグインです。

なお、このプラグインと Nginx 1.13.9 で HTTP/2 push を有効にしたサイトは以下になります。
https://lets.ninja/

Let's Ninja !

10
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?