読者です 読者をやめる 読者になる 読者になる

takedajs ログ

備考録

Gulpを利用してJavaScriptとCSSを圧縮する

Gulp 技術

サイト速度を最適化するために、GulpでJSとCSSの圧縮を試してみました。

Gulpが導入されいることを前提に今回の記事を書いているので、まだ導入していない方は、以下の記事を参考に導入までを行ってください。

takedajs.hatenablog.jp

今回、JSとCSSの圧縮には、以下のプラグインを利用しました。
JS : gulp-uglify
CSS: gulp-clean-css

CSS圧縮にgulp-minify-cssを利用している記事が多くあったのですが、 gulp-minify-cssは非推奨になっており、gulp-clean-cssが推奨されてるみたいです。 https://www.npmjs.com/package/gulp-minify-css

圧縮プラグイン導入

・JSを圧縮するプラグインを導入

npm install gulp-uglify --save-dev

CSSを圧縮するプラグインを導入

npm install gulp-clean-css --save-dev

・2つのプラグインが導入されたか確認

npm ls --depth=0

圧縮タスクを作成

gulpfile.jsに以下のコードを記述します。

var gulp = require('gulp');
var uglify = require('gulp-uglify');
var cleanCSS = require('gulp-clean-css');

//JS圧縮
gulp.task('minify-js', function() {
    return gulp.src("js/*.js")
        .pipe(uglify())
        .pipe(gulp.dest('dist/js/'));
        //.pipe(gulp.dest('js')); 上書きする場合
});

//CSS圧縮
gulp.task('minify-css', function() {
    return gulp.src("css/*.css")
        .pipe(cleanCSS())
        .pipe(gulp.dest('dist/css/'));
        //.pipe(gulp.dest('css')); 上書きする場合
});

JSとCSSともそれぞれのディレクトリ配下に置いたファイルを圧縮し、dist/~に圧縮したファイルを保存しています。

タスク実行と結果

JSとCSSそれぞれの圧縮前後でのコードを比較してみます。

JSの圧縮

・ターミナルで以下のタスクを実行

gulp minify-js

・圧縮前のコード(46バイト)

function test() {
    alert('テスト');
}

・圧縮後のコード(35バイト)

function test(){alert("テスト")}

CSSの圧縮

・ターミナルで以下のタスクを実行

gulp minify-css

・圧縮前のコード(47バイト)

a {
    margin: 10px;
    text-align: center;
}

・圧縮後のコード(32バイト)

a{margin:10px;text-align:center}

まとめ

Gulpを利用して簡単にJSとCSSの圧縮をすることができました。
圧縮されたあとのコードは、ファイルサイズが小さくなっているので、ページ速度に少なからず良い影響がでますね。

GTmetrixAPIでサイトのページロード時間を取得する

GTmetrix

サイトパフォーマンステストサービスであるGTmetrixAPIを利用して、 このブログのページロード時間を取得しました。

f:id:takedajs:20160924212252p:plain

GTmetrixAPIについて

詳しい説明は公式ページに掲載されているので、そちらをご確認ください。
GTmetrix REST API | GTmetrix

無料(Basic)プランと有料プランがあるのですが、今回は無料プランを利用しました。
以下、無料プランの内容です。

  • 1解析要求 = 1クレジット
  • 無料ユーザは毎日20クレジットを貰える
  • 最初のAPIキー作成で、テスト利用で使うために100クレジットを貰える

以下、料金プランです。

f:id:takedajs:20160924212306p:plain

GTmetrixAPIの利用方法

GTmetrixAPIを利用するために、API Keyを発行します。

まず、GTmetrixAPIのサイトからSign UPします。

f:id:takedajs:20160924210319p:plain

Sign UPが完了するとAPI keyが作成できるので作成します。

f:id:takedajs:20160924210344p:plain

API keyを作成するとAPI Keyや現在のクレジット数などの情報が表示されるようになります。
解析に必要なクレジットも100与えられていることが分かりますね。

f:id:takedajs:20160924211251p:plain

これで準備完了です。

GTmetrixAPIを利用する

このブログのページロード時間を取得します。

まず、このブログページを解析し、解析結果ページのurlを取得します。

curl --user [登録メールアドレス]:[APIキー] \
     --form url=http://takedajs.hatenablog.jp/ --form x-metrix-adblock=0 \
     https://gtmetrix.com/api/0.1/test

上記のcurlコマンドを叩いた結果です。
この解析をすることでクレジットが1減ります。

{"test_id":"GlDaptHf","poll_state_url":"https://gtmetrix.com/api/0.1/test/GlDaptHf"}

次に、解析結果ページのurlを元に解析結果を取得します。

curl --user [登録メールアドレス]:[APIキー] \
     https://gtmetrix.com/api/0.1/test/GlDaptHf

上記のcurlコマンドを叩いた結果です。
目的であったページロード時間であるpage_load_time(ms)が取れているとこが分かります。

{
    "error": "", 
    "resources": {
        "har": "https://gtmetrix.com/api/0.1/test/GlDaptHf/har", 
        "pagespeed": "https://gtmetrix.com/api/0.1/test/GlDaptHf/pagespeed", 
        "pagespeed_files": "https://gtmetrix.com/api/0.1/test/GlDaptHf/pagespeed-files", 
        "report_pdf": "https://gtmetrix.com/api/0.1/test/GlDaptHf/report-pdf", 
        "report_pdf_full": "https://gtmetrix.com/api/0.1/test/GlDaptHf/report-pdf?full=1", 
        "screenshot": "https://gtmetrix.com/api/0.1/test/GlDaptHf/screenshot", 
        "yslow": "https://gtmetrix.com/api/0.1/test/GlDaptHf/yslow"
    }, 
    "results": {
        "html_bytes": "18145", 
        "html_load_time": "317", 
        "page_bytes": "40431915", 
        "page_elements": "231", 
        "page_load_time": "8235", 
        "pagespeed_score": "18", 
        "report_url": "https://gtmetrix.com/reports/takedajs.hatenablog.jp/cXeiHRtQ", 
        "yslow_score": "46"
    }, 
    "state": "completed"
}

まとめ

登録からcurlコマンドでのページロード時間取得まで、簡単にできました。
ただ、より正確な数値を出すためには、定期的にページロード時間を取得して、取得結果の平均を出す必要があります。GTmetrixAPIを利用するためのPHPライブラリが提供されているので、それを利用して簡単なアプリケーションを作ってみたいと思います。

CodeIgniterでMemcachedを検証する

CodeIgniter Memcached

CodeIgniterでMemcachedの利用前後での速度比較を行いました。
サーバにMemcachedが導入され、PHPと連携ができていることを前提に今回の記事を書いています。 まだできていない方は、前回書いた記事を参考にMemcachedPHPとの連携まで行ってください。

takedajs.hatenablog.jp

環境

  • Vagrantで構築
  • CodeIgniter Version 3.1.0

Memcachedが利用できるか確認

application/config/memcached.phpに以下を追記します。
['memcached']以外のところはデフォルトですでに記述されています。

$config['memcached'] = array(
        'default' => array(
                'hostname' => '127.0.0.1',
                'port'     => '11211',
                'weight'   => '1',
        ),
);

適当なコントローラーに以下のようなコードを書いて、Memcachedドライバーが利用できるか確認します。

public function index() {
    $this->load->driver('cache', array('adapter' => 'memcached'));

    if ($this->cache->is_supported('memcached')) {
        var_dump("成功");
    } else {
        var_dump("失敗");
    }
}

検証用コード

Memcachedにkey名がcountのデータがないときに、1億回ループした値を保存しています。 既にデータが保存されている場合は、保存されている値を表示させます。 今回、CI_Benchmarkクラスを利用してベンチマークを取っています。

public function index()
{
    $this->load->driver('cache', array('adapter' => 'memcached'));

    $this->benchmark->mark('my_mark_start');

    if (!$count = $this->cache->get("count")) {
        $count = 0;
        //1億回ループ
        for ($i = 0; $i < 100000000; $i++) {
            $count += 1;
        }
        //キャッシュに60秒保持
        $this->cache->save("count", $count, 60);
    }

    $this->benchmark->mark('my_mark_end');

    print "カウント数:" . $count . "<br />";
    print "秒数:" . $this->benchmark->elapsed_time('my_mark_start', 'my_mark_end');
}

検証結果

Memcached利用前後での処理速度の結果です。 1億回のループ分早くなっていることが分かります。 サイトパフォーマンス的にキャッシュは本当偉大ですね。

Memcached利用前

f:id:takedajs:20160922092833p:plain

Memcached利用後

f:id:takedajs:20160922091642p:plain

まとめ

過去に検証した、CodeigniterのWebページキャッシュに比べ、apiのレスポンス単位でキャッシュができるので、使い勝手が良さそうです。 キャッシュするときのkey名や保持する時間に関しては、導入するサイト毎でどうするか考える必要がありますね。

Memcachedは少し前まではよく聞くワードだったのですが、最近はRedisの方がよく聞きます。 今後、CodeigniterのRedisを使ったキャッシュの検証やMemcachedを利用したときの違いなどを調査してみたいと思います。

takedajs.hatenablog.jp

Memcachedの導入とPHPとの連携

Memcached PHP

MemcachedCentOSに導入するところから、PHPで利用可能にするための連携までを書きました。インストールするものが多いので、適宜インストールしてください。

環境

Memcachedのインストール

Memcachedのインストール

wget http://www.memcached.org/files/memcached-1.4.24.tar.gz -O memcached-1.4.24.tar.gz
tar xvf memcached-1.4.24.tar.gz
cd memcached-1.4.24
sudo yum -y install libevent-devel
make
make install

Memcachedがインストールされたか確認

memcached -V

libmemcachedのインストール

wget https://launchpad.net/libmemcached/1.0/1.0.18/+download/libmemcached-1.0.18.tar.gz
tar xvf libmemcached-1.0.18.tar.gz
cd libmemcached-1.0.18
./configure
make
make install

PHPとの連携

PHPモジュールのインストール

wget http://pecl.php.net/get/memcached-2.2.4.tgz
tar xvf memcached-2.2.4.tgz
cd memcached-2.2.4
sudo yum -y install autoconf
sudo yum install php-devel
phpize
./configure --with-libmemcached-dir=/usr/local/ --disable-memcached-sasl
make
make install

php.iniに以下を追記

extension=memcache.so

php.iniのパスが分からないときは以下で確認できます。

php -i | grep php.ini

apacheの再起動

sudo systemctl restart httpd

Memcachedが呼ばれているか確認
memcachedの記述が表示されれば問題ないです。

php -i | grep memcached

Memcachedの起動と自動起動設定

Memcachedを起動

sudo systemctl start memcached

Memcachedの起動を確認

systemctl status memcached

Memcached自動起動設定

sudo systemctl enable memcached

Memcached自動起動確認

systemctl list-unit-files -t service | grep memcached

まとめ

Memcachedの導入とPHP連携ができたので、次回は実際にアプリケーション側で利用してみたいと思います。

追記 2016/9/22 アプリケーション側で利用してみました。


takedajs.hatenablog.jp

ISUCON6の予選に参加しました

ISUCON

ISUCONに初参加し、今回の感想を備考録として書きました。
技術的な話は書いていません。

毎年開催されていて自分も参加したいと思っていたので、毎週技術週報を送り合ってる@enomotodev@suga-tech3とp-teamというチーム名で初参加しました。

結果は、予選敗退でした。

利用言語:PHP
MAXスコア:14652
場所: 会社の会議室

LINEカフェの申し込みをし忘れたため、会社の会議室を借りました。 結果的には周りに人がいない会議室の方が集中できたと思うので良かったです。

開催前

8:30 - 9:00
デスクトップ、机、椅子など準備

9:00 - 9:30
Bitbucketを導入
(@enomotodevが事前にAzureの設定をやってくれました。)

9:30 - 10:00
だらだら

開催中

午前中

10:00 - 11:30
・Azureへ接続
・なぜかPHPが動かなかったので、動くように設定
・コードなどを見て、施策を出してスプレットシートにまとめる

11:30 - 12:30
マクドナルドを食べながら、午前の進捗共有
・午前でのベストスコアは4332

午後

12:30 - 16:00
・午前中に考えた施策を実施。
 インフラなどメインで行ったが、ほとんど効果がでませんでした。
 あと、MySQLにインデックスを貼ったんですが、これも思ったより効果なかったです。

16:00 - 17:55
・entryテーブルをSELECTしているsqlをチューニングしたら、4000→14620に数値が跳ね上がってビビる。あ、チューニングすべきところはここだったね、と気づく。
・starの取得方法を変更

17:55 - 18:00
・最後のベンチマークを計測し、終了。
・後輩が買ってきてくれたカップ焼きそばの準備
(ニコニコ超会議ドワンゴのエンジニアが焼きそばを焼いてる記事に影響を受けて、買ってきたみたいです笑)←違ったみたいです笑

開催後

18:00 - 18:30
・カップ焼きそばを食べながら振り返り。

18:30 - 19:00
・片付け
・解散

振り返り

  • サーバーやMySQLのチューニングに時間を割きすぎた
    サーバーの設定弄ればドカンと早くなるんでしょ?と余裕ぶっこき過ぎました。もっと、コードをもっとよめば良かったです。午前中にコードをざっと読んだときに、character_lengthらへんの処理を見て、ここ怪しいなとは思ったのですが、対応が終了間際になってしまいました。

  • モニタリングツールを導入した方が良かった
    遅い箇所を視覚的に常に見えるようにしとくべきだった。コードを読めばどこを修正すべきかは分かるのですが、モニタリングツールを導入することで、効率的に施策を考えられ、優先順位をつけて実装できたんじゃないかなと思います。知り合いは、NewRelicを使ってたみたいです。
    ISUCON6 オンライン予選に出て惨敗してきました。 - 日頃の行い

  • インフラの知識が足りない
    3人ともアプリケーションエンジニアだったため、インフラの設定や施策出しに課題がありました。 基礎的なところや、これだけはやっとけみたいなものを覚えておくだけでも違うと思うので、次回までには身につけておきたいです。

まとめ

業界でもトップのエンジニアの方と同じ問題を解く経験は、とても良い刺激になりました。
来年こそは決勝に行きたいので、普段の業務でも更にパフォーマンスを意識して開発を行い、レベルアップして次回も挑戦したいです!
運営の皆様、良い機会を作ってくださりありがとうございました!