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

yamachan.log

紫陽花

Rails CarrierWave アップロード画像を良い感じに圧縮するGem作った

Rails CarrierWave アップロード画像を良い感じに圧縮するGem作った

Railsで画像アップロードを行うGemにCarrierWaveがあります。 そのCarrierWaveのextension的位置付けの圧縮機能を簡単に実装するGemを作りました。

carrierwave-optimize_image

Ruby Gems

作った背景

単純に画像圧縮機能が欲しくなった場面があったため作った。

あと、PageSpeed Insightsでサイトの計測を行うと画像の圧縮を推奨されるため最適化のためです。

この手のGemは実は既に何個か作られていたりして、調べた限りでは以下のGemが類似しているものです。 Gem名も似た感じですね。

これらのGemに気になる点がみつかり、自分でそれらの点を解決したものを作ろうと思ったので今回新しく自分で作りました。 それぞれで気になった点を簡単に紹介します。

  • Pietの気になった点

    実際のプロダクトにはPietを採用しました。 Pietを採用した理由は、GemのDL数の多さから信用性があると自分で判断したことと。pngquantに対応しているため圧縮効率が良い 2017/2の時点で 247,136 DL pngquantの圧縮機能はPietに付随した別のGemを流用しており、共通のインターフェースを提供していないため使い勝手が悪い。

    ``` Piet.optimize

    Piet.pngquant ```

    また、現状問題なく動いているものの付随したGemのpng_quantizatorは4年ほど前に作られており、 その後にはほとんど手もつけられていないため不安しかなかった。

  • carrierwave-imageoptimizerの気になった点

    carrierwave-imageoptimizerは最初に導入を検討していました。 2017/2の時点で 108,841 DL 圧縮効率の良いpngquantではなくoptpngを使っていた。pngquantの方がoptpngよりも半分近く圧縮できる。 その結果、パフォーマンス的に良くないため不採用 またGem内で画像拡張子による圧縮対象の分岐(png用, jpeg用)などの処理がなく。 ただ単純にimage_optimizerに処理を丸投げ(委譲)してるだけの仕様はなんか嫌だった。 もともとimage_optimizerがメインで、そのおまけ感覚でcarrierwave用のを作ったみたい

  • carrierwave-imageoptimの気になった点

    一番最近作られたGem 見た感じ色々なオプションを選択できる仕様になっていて良さそう。 今回は単純にjpegpngを効率良く圧縮できるシンプルなインターフェースを持ったものを欲しかった。 なので複雑なオプションなどは不要だったため不採用。

  • まとめると

    「CarrierWaveを簡単に拡張した画像圧縮機能で、かつ圧縮効率が良く。使い勝手の良い統一的なインターフェースを持った。 2017年2月現在の環境で安心して使うことができるGem」を目指して作ったのがcarrierwave-optimize_imageです。

導入方法は簡単で、

brew install for Mac

brew install jpegoptim pngquant

Gem install

gem "carrierwave-optimize_image"

CarrierWave

  class ImageUploader < CarrierWave::Uploader::Base
    include CarrierWave::OptimizeImage
    ...
    process :optimize
  end

optimizeで簡単に画像をアップロードするタイミングで圧縮処理がかかり、画像が圧縮されます。

今後検討したい機能

  • pngjpegそれぞれで画像の圧縮効率をオプションで変更できるようにする。現状は統一した圧縮効率 例: pngが60%圧縮 jpegが40%圧縮

  • エラー処理の対応をもっと親切なものにする

  • pngjpeg以外の拡張子にも対応していく

  • 今後さらに圧縮効率の良いものがそれらを対応していく

他にもあれば随時変更していきたい。

まとめ

  • 初めてGemを作って公開できて良い経験になった
  • Gem作成〜公開〜導入までの流れが一通り理解できた
  • 画像圧縮上手くいった
  • 課題意識とそれを解決する手段を考える意識がついた
  • 今後も何かアイデアが浮かんだときに作りたい

試しに使ってみてもらえたら嬉しいです! PullRequestや要望、フィードバックなども大歓迎です!