gulp-imageminとpngquantを使って画像圧縮を効率化する

2月からつみきに入社した、フロントエンドエンジニアの高松です。

期間目標のひとつに「文章力をあげたい」と書いてみたところ、「それなら、ブログに記事を書いてみたら?」と言われ、早速記事を書くことになりました。
展開のはやさにびっくりです。

というわけで、今回はgulpを使った画像圧縮について書いてみようかと思います。

なぜ画像を圧縮する必要があるのか

昨今のスマートフォンの普及によって、我々エンジニアもスマートフォン向けサイトを制作する機会が多くなりましたが、スマートフォンはあらゆる場所で利用されるため、常に高い通信速度を保てるわけではありません。
そのため、サイトの制作時には通信速度の遅い状況でもストレス無く表示できるように気をつけなければなりません。

PC向けサイトにおいても、ページの表示速度はユーザーの印象に影響を与える重要な要素ですので、できるだけファイルサイズを抑えて通信の量を減らしたいところです。


そのような場合に最もわかりやすくファイルサイズを減らすことができるのが、画像の圧縮です。

TinyPNG

上記のようなwebサービスを使えば、ドラッグ・アンド・ドロップをするだけで手軽に画像を圧縮してくれます。

しかも、画像によってはファイルサイズが3分の1以下になります。
これは使わない手はないです。

gulpを使って画像の圧縮を効率化する

ただ、webサービスを使った画像圧縮は確かに手軽なんですが、一度に処理できる数に制限があることが多いです。
また、画像に変更がある度に毎回webサービスにドラッグ・アンド・ドロップするのは少し面倒です。

そこで今回はビルドシステムであるgulp.jsを使って、画像の圧縮をまとめて処理してみます。


使用するモジュールは次のとおりです。

coffee-scriptはgulpfileをCoffeeScriptで書くために使用しているので、JavaScriptで書く場合は必要ありません。
画像圧縮の役割を担ってくれるのはgulp-imageminになります。

まずは上記のモジュールをインストールします。(Node.jsがインストール済みであること)

npm i -D gulp gulp-imagemin coffee-script

次に、gulp用のタスクを書いたgulpfile.coffeeを用意します。

#gulpfile.coffee
gulp      = require 'gulp'
imagemin  = require 'gulp-imagemin'
imagePath =
  src:  './src/images/'
  dist: './dist/images/'

gulp.task 'optimizeImage', ->
  gulp.src imagePath.src + '**/*'
    .pipe imagemin()
    .pipe gulp.dest imagePath.dist

gulp.task 'default', ['optimizeImage']

あとはgulpコマンドを実行するだけで、/src/images/ディレクトリにある画像を圧縮して/dist/images/ディレクトリに書き出してくれます。

JavaScriptやCSSの圧縮処理などもこちらのタスクに組み込めば、コマンドひとつで軽量なファイル郡を生成できます。
これで早く家に帰ることができますね!

圧縮方法を変更してみる

上記の方法でpngファイルを圧縮してみると分かるのですが、元ファイルに比べて2割程しかファイルサイズが減らないことが多く、前述のTinyPNGに比べて圧縮率が高くありません

これは、gulp-imageminがpngファイルを圧縮する際に標準で使用しているOptiPNGが、圧縮率を上げることよりも画質を保つようなつくりになっているためのようです。

今回はより圧縮率の高いオプティマイザー、pngquantを使用してpng画像を圧縮してみます。(TinyPNGも内部でこちらを使用しているようです)

gulp-imageminでpngquantを使えるようにするため、imagemin-pngquantをインストールします。

npm i -D imagemin-pngquant

pngquantを使用して圧縮するようにタスクを変更します。

#gulpfile.coffee
gulp      = require 'gulp'
imagemin  = require 'gulp-imagemin'
pngquant  = require 'imagemin-pngquant'
imagePath =
  src:  './src/images/'
  dist: './dist/images/'

gulp.task 'optimizeImage', ->
  gulp.src imagePath.src + '**/*'
    .pipe imagemin
      use: [
        pngquant
          quality: 60-80
          speed: 1
      ]
    .pipe gulp.dest imagePath.dist

gulp.task 'default', ['optimizeImage']

あまり圧縮しすぎても困るので、qualityオプションで画像品質を高めに、speedオプションで実行速度よりも品質を重視するように設定しています。

この設定で実際に圧縮してみた画像がこちら。

圧縮前の画像

圧縮前の画像

ファイルサイズ:3,638bytes

圧縮後の画像

圧縮後の画像

ファイルサイズ:1,234bytes

ファイルサイズが元のファイルの3分の1程になりました!
今回は元々ファイルサイズが小さい画像のため2KB程しか減っていませんが、サイト全体の画像を対象にすると結構な差になります。


上記のgulpを使った画像圧縮の他に、CSSスプライトや、Base64へ変換してCSSに埋め込む手法も合わせて活用することで、画像ファイルと上手に付き合っていただければと思います。

スマホアプリ制作、Web制作、UIコンサルなどのご依頼はこちら

お問い合わせ