Skip to content

Minify, bundle, and optimize CSS/JS for Rails. Your assets are covered. (See `development` branch for upcoming Rails 3 support.)

License

Notifications You must be signed in to change notification settings

caseydreier/asset_hat

 
 

Repository files navigation

AssetHat

Your assets are covered.

With Rails’ default asset caching, CSS and JS are concatenated (not even minified) at runtime when that bundle is first requested. Not good enough. AssetHat can automatically:

  • Easily minify and bundle CSS and JS on deploy to reduce file sizes and HTTP requests.

  • Load popular third-party JS (like jQuery and Prototype) from {Google’s CDN} when in production, or from localhost in development.

  • Force image URLs in your CSS to use CDN subdomains (including SSL support), not just the current host.

  • Add an image’s last Git commit ID to its CSS URLs to bust browser caches (e.g., /images/foo.png?ab12cd3).

After setup, you can use this in your layouts and views:

<%= include_css :bundle => 'application' %>
<%= include_js  :jquery, :bundles => ['plugins', 'common'] %>

Which turns into:

<link href="/stylesheets/bundles/application.min.css"
  media="screen,projection" rel="stylesheet" type="text/css" />
<script src="/javascripts/jquery-1.x.x.min.js"
  type="text/javascript"></script>
  <!-- In production, jQuery loads from Google's CDN instead. -->
<script src="/javascripts/bundles/plugins.min.js"
  type="text/javascript"></script>
<script src="/javascripts/bundles/common.min.js"
  type="text/javascript"></script>

And this in your deploy script:

rake asset_hat:minify

Tested with Rails 2.3.x. For a quick overview, see the AssetHat website. For the gritty details, check the complete docs and change history.

Installation

  1. Configure the gem:

    • If you’re using Rails 3 and/or Bundler 0.9+:

      1. Add to your app’s Gemfile: gem 'asset_hat', '0.x.x'

      2. Command-line: bundle install

    • If you’re using Rails 2.x’s config.gem:

      1. Add to your app’s config/environment.rb: config.gem 'asset_hat', :version => '0.x.x'

      2. Command-line: gem install asset_hat

  2. Add to your app’s Rakefile: require 'asset_hat/tasks'

Configuration

  1. Create the default config file:

    rake asset_hat:config
    
  2. In your app, open the new file at config/assets.yml, and set up your CSS/JS bundles according to that file’s example.

  3. Minify your bundles:

    rake asset_hat:minify
    

    This minifies all of the CSS/JS files listed in config/assets.yml, concatenates the minified code into bundle files, and adds CDN asset hosts and cache-busting commit IDs to image URLs in your CSS.

    Bundles are created as new files in public/stylesheets/bundles/ and public/javascripts/bundles/. Your original CSS/JS files remain untouched.

  4. Set your deployment script to run rake asset_hat:minify after deploying your latest CSS/JS. This overwrites previously minified bundles, and leaves your original CSS/JS files untouched.

Advanced configuration

If you manage deployments with Capistrano, see the gem’s packaged example at lib/asset_hat/capistrano.rb.

If you want shorter output during deployments, you can use ‘rake asset_hat:minify FORMAT=short` (one output line per bundle) or `FORMAT=dot` (one output line total) in your deploy script.

Additional settings are supported in config/assets.yml:

  • engine: Indicates how CSS and JS are minified; omit this setting to use the defaults. By default, CSS is minified with rgrove/cssmin (a Ruby port of Lecomte’s YUI Compressor and Schlueter’s PHP cssmin), and JS is minified with rgrove/jsmin (a Ruby port of Crockford’s JSMin).

    If you’d prefer to have slightly more readable code for debugging purposes, you can switch both the CSS and JS engines to weak. However, the weak engines don’t save as many bytes.

  • vendors: Configures third-party JS that’s loaded from a CDN or other external source. The following example configures jQuery and jQuery UI for use throughout the app:

    js:
      vendors:
        jquery:
          version:        1.4.4
        jquery_ui:
          version:        1.8.5
          remote_url:     http://cdn.example.com/js/jquery-ui-1.8.5.min.js
          remote_ssl_url: https://cdn-ssl.example.com/js/jquery-ui-1.8.5.min.js

    Configuration keys per vendor:

    • version: Sets the default version across the app. In the example above, <%= include_js :jquery %> uses version 1.4.4 by default. You can override this for special layouts/views with <%= include_js :jquery, :version => '1.3.2' %>.

    • remote_url, remote_ssl_url: By default, vendor JS will load from Google’s CDN in production (or any environment where config.action_controller.consider_all_requests_local is set to true). If the original request to your app used SSL, the vendor JS will also load from Google’s CDN via SSL. If you prefer to use a different CDN, specify its SSL/non-SSL URLs, and the appropriate URL will be used per request.

    A full list of supported vendors is in the AssetHat::JS::Vendors module.

SSL configuration

When you request a page via SSL, some browsers (euphemism for “IE”) show errors if any assets – stylesheets, JS files, images – are served without SSL.

AssetHat plays well with SSL pages that load assets from a CDN. Put this in config/environments/production.rb or similar:

config.action_controller.asset_host = Proc.new do |source, request|
  "#{request.protocol}cdn#{source.hash % 4}.example.com"
    # => 'http://cdn0.example.com', 'https://cdn1.example.com', etc.
end

This switches to a different CDN URL if the request used SSL. When you run rake asset_hat:minify at deploy time, AssetHat detects this configuration, and generates special SSL versions of each stylesheet that also load images from CDN via SSL. (Non-SSL pages still get non-SSL stylesheets.)

Usage

In your layouts and views, instead of these:

<%= stylesheet_link_tag 'reset', 'application', 'clearfix',
                        :media => 'screen,projection',
                        :cache => 'bundles/application' %>
<%= javascript_include_tag 'plugin-1', 'plugin-2', 'plugin-3',
                           :cache => 'bundles/application' %>

Use these:

<%= include_css :bundle => 'application' %>
<%= include_js  :bundle => 'application' %>

These turn into:

<link href="/stylesheets/bundles/application.min.css"
  media="screen,projection" rel="stylesheet" type="text/css" />
<script src="/javascripts/bundles/application.min.js"
  type="text/javascript"></script>

Have an enormous app? You can integrate gradually, using AssetHat alongside Rails’ default asset caching.

If your environment has config.action_controller.perform_caching set to true (e.g., in production), the layout/view will include minified bundle files. Otherwise, the separate, unminified files will be included, based on the bundle contents you define in config/assets.yml.

If your environment has config.action_controller.asset_host pointing to a CDN, your CSS/JS files will load from there. If your configuration supports using the CDN via SSL (see the section “SSL configuration”), SSL requests will also load CSS/JS files via SSL.

Advanced usage

You can also include single files as expected:

<%= include_css 'reset', 'application' %>
<%= include_js  'plugin.min', 'application' %>

Or include multiple bundles at once:

<%= include_js :bundles => %w[plugins common] %>

When including multiple bundles at once, this yields one <link> or <script> element per bundle.

You may want to use multiple bundles to separate plugins (rarely changed) from application code (frequently changed). If all code is in one huge bundle, then whenever there’s a change, browsers have to re-download the whole bundle. By using multiple bundles based on update frequency, browsers cache the rarely updated code, and only re-download the frequently updated code.

  • To crush your assets;

  • See them bundled before you; and

  • Hear no more lamentation about slow page loads.

About

Minify, bundle, and optimize CSS/JS for Rails. Your assets are covered. (See `development` branch for upcoming Rails 3 support.)

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages

  • Ruby 99.8%
  • JavaScript 0.2%