Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Decrease Deployment Time of Rails Applications by Precompiling External Assets Separately

DZone's Guide to

Decrease Deployment Time of Rails Applications by Precompiling External Assets Separately

When deploying Rails applications, the asset compilation phase can take a long time. Typically, we have much more code in our external dependencies. As the project grows, more dependencies are added and the deployment becomes depressing, especially if you deploy multiple times a day. This post will discuss one solution to this problem.

· Web Dev Zone ·
Free Resource

Deploying code to production can be filled with uncertainty. Reduce the risks, and deploy earlier and more often. Download this free guide to learn more. Brought to you in partnership with Rollbar.

When deploying Rails applications, the asset compilation phase can take a long time. Typically, we have much more code in our external dependencies. As the project grows, more dependencies are added and the deployment becomes depressing, especially if you deploy multiple times a day. This post will discuss one solution to this problem.

I recently worked on a project which had a lot of external asset dependencies (map plugins, charts, rich editors, etc.). We deployed multiple times a day on several environments (both automated and manual). Once the time limit of Heroku builds was hit, we needed to speed things up. I observed that asset compilation took most of the time. Since the majority of assets were external, I decided to compile them separately on a local machine and include the compressed files to the version control, because they never change but get compiled on every build.

The following steps explain the implementation details of this approach. First of all, create two manifest files, external.css and external.js, and move the appropriate imports from application.css and application.js to them. We will create a new environment in config/environments/external_assets.rb to override the default configuration for compiling assets:   

MyApplication::Application.configure do
  config.assets.compress = true
  config.assets.precompile = ['external.js', 'external.css']
end

Let’s write the rake task which will run precompile task. It additionally deletes the manifest.yml file which is generated, because Heroku uses this file to determine if it should compile your assets. Since we want our application assets to be compiled on builds, we will remove this file. Create the lib/tasks/external_assets.rb and paste the following code:   

namespace :external_assets do
  task precompile: :environment do
    Rake::Task['assets:precompile'].invoke
    File.delete("#{Rails.root}/public/assets/manifest.yml")
  end
end

If your application requires all Rails modules, including ActiveRecord (which is by default) you will need a database to perform any operations. Add the following lines to your config/database.yml:   

development: &development
  # ... database configuration

external_assets:
  <<: *development

Include the compressed files to your parent layout in  app/views/layouts/application.html.erb:

<%= stylesheet_link_tag "external", :media => "all" %>
<%= javascript_include_tag "external" %>

Finally, run  rake external_assets:precompile RAILS_ENV=external_assets and push the changes to your version control system. This solution speeded up our builds from ~15 minutes to less than 1 minute. We just need to recompile these assets if we add a new dependency, which doesn’t happen so often.

If you have any thoughts or questions, please don’t hesitate to share them.

Deploying code to production can be filled with uncertainty. Reduce the risks, and deploy earlier and more often. Download this free guide to learn more. Brought to you in partnership with Rollbar.

Topics:
heroku ,rails ,deployment

Published at DZone with permission of

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}