Help us understand the problem. What is going on with this article?

Apache(Heroku)+laravel+vue.js環境下でgzip圧縮によるサイトパフォーマンス向上

More than 1 year has passed since last update.

はじめに

どうも、@nittannittanです。

趣味でAndroid/iOS/Webアプリを作成しているアニメオタクです。

最近SPAとして開発をしたWebサービスの機能が増えてきたために初回アクセス時のjsロード時間が30秒ほどかかってしまうほど激遅になってしまったのでgzip圧縮で対応をしてみました。

初歩的な技術かもしれませんが、私の環境に完全に合致する記事が探せなかったので本記事を作成しました。

関係する技術

  • PHP
  • Laravel Mix
  • Vue.js
  • heroku
  • compression-webpack-plugin

1. compression-webpack-pluginをインストール

npm install compression-webpack-plugin --save-dev

2. webpack.mix.jsにcompression-webpack-pluginの記述を追加

下記の2つの処理をwebpack.mix.jsに追加しmixでのapp.js生成時に同時にgzファイルを生成する。

const CompressionPlugin = require('compression-webpack-plugin');
mix.webpackConfig({
    plugins: [
      new CompressionPlugin({
        filename: '[path].gz[query]',
        algorithm: 'gzip',
        test: /\.js$|\.css$|\.html$|\.svg$/,
        threshold: 10240,
        minRatio: 0.8,
      })
    ]
  });

追加後は下記

const mix = require('laravel-mix');
const CompressionPlugin = require('compression-webpack-plugin');//追加
/*
 |--------------------------------------------------------------------------
 | Mix Asset Management
 |--------------------------------------------------------------------------
 |
 | Mix provides a clean, fluent API for defining some Webpack build steps
 | for your Laravel application. By default, we are compiling the Sass
 | file for the application as well as bundling up all the JS files.
 |
 */


mix.js('resources/js/app.js', 'public/js')
   .sass('resources/sass/app.scss', 'public/css')
   //追加
   .webpackConfig({
    plugins: [
      new CompressionPlugin({
        filename: '[path].gz[query]',
        algorithm: 'gzip',
        test: /\.js$|\.css$|\.html$|\.svg$/,
        threshold: 10240,
        minRatio: 0.8,
      })
    ]
  });

if (mix.inProduction()) {
    mix.version();
}

3. ビルド

リリース用ビルドを実行する

npm run production

完了するとcssとjsのgzipファイルが生成されます。

スクリーンショット 2019-01-06 10.00.46.png

1/3ほどになりましたね。やったぜ。

4. .htaccessにgzipをレスポンスで返却するように設定

gzipファイルを用意しただけではレスポンスでgzipを返してはくれません。
heroku上ではapacheを利用しているので、.htaccessにgzipの設定を追加します。

    # gzip対応
    RewriteCond %{HTTP:Accept-Encoding} gzip
    RewriteCond %{REQUEST_FILENAME}\.gz -s
    RewriteRule ^(.+) $1.gz

    <FilesMatch "\.css\.gz$">
        ForceType text/css
        AddEncoding x-gzip .gz
    </FilesMatch>
    <FilesMatch "\.js\.gz$">
        ForceType application/x-javascript
        AddEncoding x-gzip .gz
    </FilesMatch>

    Header append Vary Accept-Encoding env=!dont-vary

laravelはもともと.htaccessでindex.phpへのリダイレクトをコントロールしているため追加後は下記のようになります。

<IfModule mod_rewrite.c>
    <IfModule mod_negotiation.c>
        Options -MultiViews -Indexes
    </IfModule>

    RewriteEngine On

    # Handle Authorization Header
    RewriteCond %{HTTP:Authorization} .
    RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]

    # Redirect Trailing Slashes If Not A Folder...
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_URI} (.+)/$
    RewriteRule ^ %1 [L,R=301]

    # Handle Front Controller...
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^ index.php [L]

    # gzip対応
    RewriteCond %{HTTP:Accept-Encoding} gzip
    RewriteCond %{REQUEST_FILENAME}\.gz -s
    RewriteRule ^(.+) $1.gz

    <FilesMatch "\.css\.gz$">
        ForceType text/css
        AddEncoding x-gzip .gz
    </FilesMatch>
    <FilesMatch "\.js\.gz$">
        ForceType application/x-javascript
        AddEncoding x-gzip .gz
    </FilesMatch>

    Header append Vary Accept-Encoding env=!dont-vary
</IfModule>

今回の環境に不要なプロキシの設定も最後にありますが、各自で判断して記載してください。
ちなみに私は.htaccessに食わず嫌い的な苦手意識があるので参考サイトのほぼコピーです。。。

それを少し改善しようと思ったので下記を確認して少し理解はしておきました。

https://html-coding.co.jp/knowhow/tips/wp_modrewrite/
https://github.com/EC-CUBE/ec-cube/issues/1607

5. Heroku環境にデプロイして動作確認

普段と同じようにHerokuにgit pushを行ってリリースします。
その後ChromeのDevToolsでリクエストとレスポンスを確認します。

Content-Lengthもgzipファイルと同じサイズですし、Content-Encodingもx-gzipになっているので成功していそうですね。

スクリーンショット 2019-01-06 10.26.09.png

雰囲気で.htaccessをコピペして試したらうまく言っているようなのでうまく行き過ぎて不安は感じましたが.htaccessを再確認しても不明点や問題になりそうなものもないため良しとします。
間違いがあればご指摘していただけると嬉しいです。

Laravel Mixについて

Laravelを仕事で使いそうという理由でLaravelを選択しせっかくだからSPAにしようということでドキュメントに従ってLaravel Mixを利用していますが、日本語の記事をあまり見かけないので流行っていないのかもと心配になりますね。ただとても簡単にwebpackの環境が導入できたのでLaravel Mixはとても気に入っています。簡単に使えるから特に迷うこともなくて記事が少ないというのもあるかもしれませんね。

開発しているWebサービス(LAR)について

LARは放送時期(クール)ごとにアニメを一覧で見ることができるサービスです。
ログイン不要で自由にアニメの一覧が作成できる「おすすめアニメメーカー」やアニメのランキングが自由に作成できる「アニメランキングメーカー」などの機能があります。

参考サイト

https://github.com/webpack-contrib/compression-webpack-plugin

https://murashun.jp/blog/20141223-01.html

https://hyper-text.org/archives/2012/11/webcontents_gzip.shtml

https://stackoverflow.com/questions/50136195/how-to-include-webpack-plugins-when-using-laravel-mix

nittannittan
Android/iOS/Webアプリを趣味で開発しています。
https://nittannittan.wordpress.com/
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