Tips for Rails Asset Pipeline   03 Jun 2012

Since Rails 3.1 a new approach of handling assets has been introduced, bringing up new workflows and fresh ideas. Asset pipeline is the new mechanism to help on the critical field of backend-frontend integration.

Assets should be easy to create, manage and integrate to the workflow of a modern web application. This has been addressed by the arrival of high level asset languages and frameworks (Coffeescript, Sass) and the pre-processing of assets in a pipelined manner. Assets should be served with the minimum number of browser requests to decrease page loading time. This is handled by concatenation of the asset partials. To reduce load and bandwidth consumption from asset downloading compression(decrease file size), and cache busting are used. Cache busting is a new caching strategy which uses file checksums in asset file names.

All these and more are included in asset pipeline. You can find more details here. And here is the 3.1 release post. Below, I am trying to group a set of useful tips and tricks that I have used in my everyday work. I suppose that rails >=3.1 is used.

Tips

  • Javascript runtime

    To use the coffeescript pre-processor a Javascript runtime environment is needed. nodejs or therubyracer are common choices for this. This is used in development but it is also needed when (and where) we run assets:precompile rake task.
      group :assets do
        gem 'sass-rails',   '~> 3.2.3'
        gem 'coffee-rails', '~> 3.2.1'
        gem 'therubyracer'
        gem 'uglifier', '>= 1.0.3'
      end
      
    
  • Background images in stylesheet files

    To include a background image in a stylesheet Sass file, the sass asset helper image-url should be used:
      .icon{
        background:image-url("sprites.png") no-repeat -36px -373px;
      }
      
    
    Alternatively (though a bit ugly), an .erb extension can be appended to the filename of the stylesheet file and the asset_path helper can be used instead:
      .icon{
        background:url(<%= asset_path ("sprites.png") %>) no-repeat -36px -373px;
      }
      
    
  • Include font assets with font-face

    To include a non-standard font, make a fonts dir under app/assets and put the font related files (e.g. the .ttf file) there. Then add the path to the folder in the config.assets.paths parameter.
      class Application < Rails::Application
        ...
        config.assets.paths << "#{Rails.root}/app/assets/fonts"
        ...
      end
      
    
    Finally, to use the font assets in Sass stylesheets, point to the correct path by using the font-path helper:
      @font-face {
        font-family: 'customfont';
        src: url(font-path('Custom-font.ttf'))  format('truetype');
      }
      
    
  • Lookup paths for assets in a rails application

    All the asset paths of a rails application can be observed by rails console:
      [7] pry(main)> Rails.application.config.assets.paths
      => ["/home/dummyuser/dummyapp/app/assets/fonts",
      "/home/dummyuser/dummyapp/app/assets/images",
      "/home/dummyuser/dummyapp/app/assets/javascripts",
      "/home/dummyuser/dummyapp/app/assets/stylesheets",
      "/home/dummyuser/dummyapp/vendor/assets/javascripts",
      "/home/dummyuser/dummyapp/vendor/assets/stylesheets",
      "/home/dummyuser/.rbenv/versions/1.9.3-p125/lib/ruby/gems/1.9.1/gems/rails3-jquery-autocomplete-1.0.7/lib/assets/javascripts",
      "/home/dummyuser/.rbenv/versions/1.9.3-p125/lib/ruby/gems/1.9.1/gems/jquery-rails-2.0.2/vendor/assets/javascripts",
      "/home/dummyuser/.rbenv/versions/1.9.3-p125/lib/ruby/gems/1.9.1/gems/coffee-rails-3.2.2/lib/assets/javascripts",
      "/home/dummyuser/.rbenv/versions/1.9.3-p125/lib/ruby/gems/1.9.1/gems/bootstrap-sass-2.0.2/vendor/assets/images",
      "/home/dummyuser/.rbenv/versions/1.9.3-p125/lib/ruby/gems/1.9.1/gems/bootstrap-sass-2.0.2/vendor/assets/javascripts",
      "/home/dummyuser/.rbenv/versions/1.9.3-p125/lib/ruby/gems/1.9.1/gems/bootstrap-sass-2.0.2/vendor/assets/stylesheets",
      "/home/dummyuser/dummyapp/app/assets/fonts"]
      
    
  • Prefer Sass @imports over Sprockets manifest syntax

    As sass-rails documentation states:
    Sprockets provides some directives that are placed inside of comments called require, require_tree, and require_self. DO NOT USE THEM IN YOUR SASS/SCSS FILES. They are very primitive and do not work well with Sass files. Instead, use Sass's native @import directive which sass-rails has customized to integrate with the conventions of your rails projects.
    By using @import directive, you exploit all the cool features of Sass, whereas require* are very restrictive. For example, you can import all the partials you need directly from the base file. If you would use Sprocket, you would have to import the partials in a secondary file which would be included with the require command in the manifest.
    WARNING: If you use @import remember to use the .scss extension with your file name, in order to be preprocessed by the Sass compiler.
  • Use precompile array in production

    All asset files which will be mapped by cache busting mechanism should be precompiled. All non-JS/CSS are automatically included to the precompile array! But if you have .css and/or .js (e.g. "admin.js", "general.css") files, they must be manually added to the precompile array ("application.js" and "application.css" are exceptions. They are included by default.):
      # Precompile additional assets (application.js, application.css, and all non-JS/CSS are already added)
      config.assets.precompile += %w( admin.css admin.js jquery-ui.js jquery.ui.css)
      
    
    In order to be sure that all your asset files are correctly precompiled, check in the generated manifest.yml.\ You should see an entry for each of them.