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.

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:

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:

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:

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

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.

Follow me

Sadzid Suljic

Software Developer at Cron
Full-stack developer with experience in developing on various application stacks. I strive to learn something new and apply the best practices on a daily basis.
Follow me
Sadzid SuljicDecrease deployment time of Rails applications by precompiling external assets separately