Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
7
Help us understand the problem. What is going on with this article?
@wokamoto

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

More than 3 years have passed since last update.

先日リリースされた 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 !

7
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
wokamoto
digitalcubeinc
デジタルキューブは AWS Partner Network (APN) アドバンスドテクノロジーパートナーです。

Comments

No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
7
Help us understand the problem. What is going on with this article?