blog

初めての Middleman シリーズ初めてのMiddleman:HTML/CSS/JS/画像をビルド時に圧縮する

    • Ryuichi Nonaka
    この記事は書かれてから1年以上経過しており、内容が古い場合があります。

    前回の記事初めてのMiddleman:Amazon S3にビルドされたファイルを同期するでビルドされたファイルをAmazon S3に同期する方法を覚えました。今回はビルド時にHTML, CSS, JS, 画像を圧縮する方法について勉強します。

    必要な拡張機能

    各種ファイルを圧縮するには拡張機能を利用します。CSSとJSの圧縮はプリインされているので拡張機能をインストールする必要はありません。ちなみにCSSはSassのコンパイルオプションで補うこともできます。HTMLと画像を圧縮するには追加でプラグインをインストールします。

    拡張機能はGemfileに追記してインストールします。

    Gemfile

    source "https://rubygems.org"
    
    gem 'middleman'
    gem 'middleman-blog'
    gem 'middleman-livereload'
    gem 'middleman-minify-html'
    gem 'middleman-imageoptim'
    gem 'middleman-s3_sync'
    
    # For feed.xml.builder
    gem 'builder'
    
    # For css.scss
    gem 'bourbon'
    gem 'neat'
    

    インストールを実行

    いつも通りインストールを実行します。

    $ bundle install
    Fetching gem metadata from https://rubygems.org/........
    Fetching additional metadata from https://rubygems.org/..
    Resolving dependencies...
    Using CFPropertyList 2.3.0
    Using i18n 0.6.11
    Using json 1.8.2
    Using minitest 5.5.1
    Using thread_safe 0.3.4
    Using tzinfo 1.2.2
    Using activesupport 4.1.9
    Using addressable 2.3.6
    Using ansi 1.4.3
    Using sass 3.4.11
    Using thor 0.19.1
    Using bourbon 4.1.1
    Using builder 3.2.2
    Using bundler 1.7.6
    Using hitimes 1.2.2
    Using timers 4.0.1
    Using celluloid 0.16.0
    Using chunky_png 1.3.3
    Using coffee-script-source 1.9.0
    Using execjs 2.3.0
    Using coffee-script 2.3.0
    Using multi_json 1.10.1
    Using compass-core 1.0.3
    Using compass-import-once 1.0.5
    Using rb-fsevent 0.9.4
    Using ffi 1.9.6
    Using rb-inotify 0.9.5
    Using compass 1.0.3
    Using eventmachine 1.0.6
    Using http_parser.rb 0.6.0
    Using em-websocket 0.5.1
    Using erubis 2.7.0
    Using excon 0.44.1
    Installing exifr 1.2.0
    Using fission 0.5.0
    Using formatador 0.2.5
    Using mime-types 2.4.3
    Using net-ssh 2.9.2
    Using net-scp 1.2.1
    Using fog-core 1.28.0
    Using mini_portile 0.6.2
    Using nokogiri 1.6.6.2
    Using fog-xml 0.1.1
    Using fog-atmos 0.1.0
    Using fog-json 1.0.0
    Using ipaddress 0.8.0
    Using fog-aws 0.1.0
    Using inflecto 0.0.2
    Using fog-brightbox 0.7.1
    Using fog-ecloud 0.0.2
    Using fog-profitbricks 0.0.1
    Using fog-radosgw 0.0.3
    Using fog-sakuracloud 1.0.0
    Using fog-serverlove 0.1.1
    Using fog-softlayer 0.4.0
    Using fog-storm_on_demand 0.1.0
    Using fog-terremark 0.0.3
    Using fog-vmfusion 0.0.1
    Using fog-voxel 0.0.2
    Using fog 1.27.0
    Installing fspath 2.1.1
    Using tilt 1.4.1
    Using haml 4.0.6
    Using hike 1.2.3
    Using uber 0.0.13
    Using hooks 0.4.0
    Installing htmlcompressor 0.1.2
    Installing image_size 1.4.1
    Installing in_threads 1.3.1
    Installing progress 3.1.0
    Installing image_optim 0.20.2
    Installing image_optim_pack 0.2.1.20150203
    Using kramdown 1.5.0
    Using listen 2.8.5
    Using map 6.5.5
    Using padrino-support 0.12.4
    Using padrino-helpers 0.12.4
    Using rack 1.6.0
    Using rack-test 0.6.3
    Using middleman-core 3.3.7
    Using sprockets 2.12.3
    Using sprockets-helpers 1.1.0
    Using sprockets-sass 1.3.1
    Using middleman-sprockets 3.4.1
    Using uglifier 2.7.0
    Using middleman 3.3.7
    Using middleman-blog 3.5.3
    Installing middleman-imageoptim 0.2.0
    Using rack-livereload 0.3.15
    Using middleman-livereload 3.4.2
    Installing middleman-minify-html 3.4.0
    Using pmap 1.0.2
    Using ruby-progressbar 1.7.1
    Using unf_ext 0.0.6
    Using unf 0.1.4
    Using middleman-s3_sync 3.0.41
    Using neat 1.7.1
    Your bundle is complete!
    It was installed into ./vendor/bundle
    

    ビルド時に圧縮されるように設定する

    config.rbに設定を書き加えます。

    Sassオプションによる圧縮を行っている場合

    configure :build do
    
      compass_config do |config|
        config.output_style = :compressed
        config.line_comments = false
      end
    
      activate :minify_javascript
      activate :minify_html
      activate :imageoptim
    
    end
    

    Sassオプションを使わない場合

    configure :build do
    
      activate :minify_css
      activate :minify_javascript
      activate :minify_html
      activate :imageoptim
    
    end
    

    ビルド

    ビルドコマンドを実行してみます。

    $ middleman build
       identical  build/assets/css/common.css
       identical  build/assets/css/sections/home.css
       identical  build/assets/images/thumbnail-256.png
       identical  build/assets/images/owl/grabbing.png
       identical  build/assets/images/teaser/background.png
       identical  build/assets/images/favicon.png
       identical  build/assets/images/teaser/background.jpg
       identical  build/assets/images/teaser/eyecatch.jpg
       identical  build/assets/images/owl/AjaxLoader.gif
       identical  build/assets/fonts/font-awesome/fontawesome-webfont.svg
       identical  build/assets/fonts/stroke7/Pe-icon-7-stroke.svg
       identical  build/assets/fonts/font-awesome/fontawesome-webfont.woff
       identical  build/assets/fonts/stroke7/Pe-icon-7-stroke.woff
       identical  build/assets/fonts/museo/260242_0_0.woff
       identical  build/assets/fonts/font-awesome/FontAwesome.otf
       identical  build/assets/fonts/museo/260242_0_0.ttf
       identical  build/assets/fonts/font-awesome/fontawesome-webfont.ttf
       identical  build/assets/fonts/stroke7/Pe-icon-7-stroke.ttf
       identical  build/assets/fonts/stroke7/Pe-icon-7-stroke.eot
       identical  build/assets/fonts/museo/260242_0_0.eot
       identical  build/assets/fonts/font-awesome/fontawesome-webfont.eot
          update  build/assets/js/libs.js
          update  build/assets/js/common.js
          update  build/index.html
          create  build/imageoptim.manifest.yml
      pngout worker: `pngout` not found; please provide proper binary or disable this worker (--no-pngout argument or `:pngout => false` through options)
    svgo worker: `svgo` not found; please provide proper binary or disable this worker (--no-svgo argument or `:svgo => false` through options)
      imageoptim  build/assets/images/owl/AjaxLoader.gif (5.08% / 77B smaller)
      imageoptim  fixed file mode on build/assets/images/owl/AjaxLoader.gif file to match source
      imageoptim  build/assets/images/owl/grabbing.png (2.59% / 3B smaller)
      imageoptim  build/assets/images/favicon.png (29.01% / 978B smaller)
      imageoptim  fixed file mode on build/assets/images/favicon.png file to match source
      imageoptim  build/assets/images/teaser/eyecatch.jpg (3.38% / 634B smaller)
      imageoptim  fixed file mode on build/assets/images/teaser/eyecatch.jpg file to match source
      imageoptim  build/assets/images/teaser/background.jpg (15.21% / 15KiB smaller)
      imageoptim  fixed file mode on build/assets/images/teaser/background.jpg file to match source
      imageoptim  build/assets/images/thumbnail-256.png (9.43% / 1KiB smaller)
      imageoptim  fixed file mode on build/assets/images/thumbnail-256.png file to match source
      imageoptim  build/assets/images/teaser/background.png (27.06% / 108KiB smaller)
      imageoptim  build/imageoptim.manifest.yml updated
      imageoptim  Total savings: 127KiB
    

    画像の圧縮が行われていますね。HTMLも改行が削除されています。

    圧縮に関する設定

    圧縮について細かく制御するにはactivateの際に設定を加えてやります。

    Middleman-Minify-HTML

    Middleman-Minify-HTML Configuration

    activate :minify_html do |html|
      html.remove_multi_spaces        = true   # Remove multiple spaces
      html.remove_comments            = true   # Remove comments
      html.remove_intertag_spaces     = false  # Remove inter-tag spaces
      html.remove_quotes              = true   # Remove quotes
      html.simple_doctype             = false  # Use simple doctype
      html.remove_script_attributes   = true   # Remove script attributes
      html.remove_style_attributes    = true   # Remove style attributes
      html.remove_link_attributes     = true   # Remove link attributes
      html.remove_form_attributes     = false  # Remove form attributes
      html.remove_input_attributes    = true   # Remove input attributes
      html.remove_javascript_protocol = true   # Remove JS protocol
      html.remove_http_protocol       = true   # Remove HTTP protocol
      html.remove_https_protocol      = false  # Remove HTTPS protocol
      html.preserve_line_breaks       = false  # Preserve line breaks
      html.simple_boolean_attributes  = true   # Use simple boolean attributes
    end
    

    Middleman ImageOptim Extension

    Middleman ImageOptim Extension Usage

    activate :imageoptim do |options|
      # Use a build manifest to prevent re-compressing images between builds
      options.manifest = true
    
      # Silence problematic image_optim workers
      options.skip_missing_workers = true
    
      # Cause image_optim to be in shouty-mode
      options.verbose = false
    
      # Setting these to true or nil will let options determine them (recommended)
      options.nice = true
      options.threads = true
    
      # Image extensions to attempt to compress
      options.image_extensions = %w(.png .jpg .gif .svg)
    
      # Compressor worker options, individual optimisers can be disabled by passing
      # false instead of a hash
      options.advpng    = { :level => 4 }
      options.gifsicle  = { :interlace => false }
      options.jpegoptim = { :strip => ['all'], :max_quality => 100 }
      options.jpegtran  = { :copy_chunks => false, :progressive => true, :jpegrescan => true }
      options.optipng   = { :level => 6, :interlace => false }
      options.pngcrush  = { :chunks => ['alla'], :fix => false, :brute => false }
      options.pngout    = { :copy_chunks => false, :strategy => 0 }
      options.svgo      = {}
    end
    

    エラーが出た

    このようなエラーが出たらpngoutとsvgoがインストールされていないためです。

    pngout worker: `pngout` not found; please provide proper binary or disable this worker (--no-pngout argument or `:pngout => false` through options)
    svgo worker: `svgo` not found; please provide proper binary or disable this worker (--no-svgo argument or `:svgo => false` through options)
    

    特に利用する予定がなければオプションからオフにします。

        options.pngout    = false
        options.svgo      = false
    

    pngoutを使いたい場合はこちらimage_optimを使ってMiddlemanのBuild時に画像を圧縮しようを参考に。svgoはnpmが必要です。npm環境が整っている前提dえインストールする場合は$ npm install -g svgoとなります。

    Middlemanは導入敷居が低いのが良いですね。
    今回はここまで。また書きたいことができたら次の記事を書きたいと思います。

    次回:初めてのMiddleman:設定について

    シリーズ

    1. 初めてのMiddleman:rbenv, bundler 環境でMiddlemanを使ったHello World
    2. 初めてのMiddleman:レイアウト機能でレイアウトとコンテンツを分離する
    3. 初めてのMiddleman:パーシャルを使ったコンテンツのモジュール化
    4. 初めてのMiddleman:SCSSのコンパイルとテンプレートの基礎
    5. 初めてのMiddleman:Sass MixinライブラリのBourbon, Neatを導入してみる
    6. 初めてのMiddleman:データファイルとデータファイルを使った動的ページ生成
    7. 初めてのMiddleman:サイトにブログ機能を追加する
    8. 初めてのMiddleman:Amazon S3にビルドされたファイルを同期する
    9. 初めてのMiddleman:HTML/CSS/JS/画像をビルド時に圧縮する
    10. 初めてのMiddleman:設定について
    11. 初めてのMiddleman:静的サイトのキャッシュとasset_hash拡張を使ったキャッシュのパージ
    12. 初めてのMiddleman:Middleman::S3Syncで使うAWS IAMユーザーのアクセスキー管理方法について
    13. 初めてのMiddleman:Helperを使ってGravatarのアイコンを表示する
    14. 初めてのMiddleman:アセットパイプラインを使った外部アセットファイルの読み込みと結合
    15. 初めてのMiddleman:Bowerを使ってjQueryなどのライブラリをロードする
    16. 初めてのMiddleman:スケルトンを自作する方法
    17. 初めてのMiddleman:Middleman Blogの記事データを使いやすく管理する方法
    18. 初めてのMiddleman:Middleman-blogのシングルブログを前提としたSkeletonを作った
    19. 初めてのMiddleman:Middleman-blogでマルチブログを試してSkeletonを作った
    20. 初めてのMiddleman:Markdown EngineをkramdownからRedcarpetに切り替える
    21. 初めてのMiddleman:RedcarpetとMiddleman::Rougeを使ったシンタックスハイライト
    22. 初めてのMiddleman:Middleman-Syntaxを使ったシンタックスハイライト
    23. 初めてのMiddleman:Middleman-Blogで記事毎に画像を管理する方法
    24. 初めてのMiddleman:Gulpを使ってサムネイル画像を生成する
    25. 初めてのMiddleman:Middleman-OGPのOGP画像指定を相対パスで設定する
    26. 初めてのMiddleman:Middleman-OGPでMiddleman-BLogにOGPを設定する
    27. 初めてのMiddleman:Middleman-Titleでタイトルタグを手軽に設定する
    28. 初めてのMiddleman:多言語化 - 言語ファイルの作成とヘルパーの埋め込み
    29. 初めてのMiddleman:Middleman-blogにカテゴリやシリーズなどのカスタムコレクションを追加する方法
    30. 初めてのMiddleman:Bowerで管理されているフォントファイルをインポートする

    コメント・フィードバック