Many web developers sooner or later have a question about speeding up the loading of their sites. This is due to the fact that not everyone has megabit channels, and some users are still on dialup. In this article I will describe how to compress javascripts for production, merge them into one file, as well as further improvements. Suppose we have a set of scripts: swfobject.js, jquery-1.3.2.js, jquery.media.js, jquery.markitup.js, jquery.markitup.set.js, application.js. Their size is about 150 KB, the packer will compress them to 50 KB.
I used to use asset_packager, but its capabilities are modest, it just deletes comments, extra spaces, and line breaks in javascript and css files. Therefore, I began to look for another way. I offer you my solution.
Install heme packr
Add a line to the config / environment.rb file
config. gem 'packr',: lib => false
and run sudo rake gems: install
')
Creating a list of script files
Create a config / js_files.yml that has the contents of a normal nest file:
base:
- swfobject. js
- jquery - 1.3.2. js
- jquery. media . js
- jquery. markitup . js
- jquery. markitup . set . js
- application. js
File initialization
To get the list of files, create the file initializers / javascript_files.rb
JAVASCRIPT_FILES = YAML :: load ( File . Read ( "# {RAILS_ROOT} /config/js_files.yml" ) ) . symbolize_keys
if RAILS_ENV == "production"
JAVASCRIPT_FILES_PACKED = Proc . new { prod_files = { } ; JAVASCRIPT_FILES. each { | key, value | prod_files [ key ] = value. map { | v | "packed /" + v } } ; prod_files } . call
ActionView :: Helpers :: AssetTagHelper . register_javascript_expansion JAVASCRIPT_FILES_PACKED
else
ActionView :: Helpers :: AssetTagHelper . register_javascript_expansion JAVASCRIPT_FILES
end
From this code it is clear that the paths for javascript in production are changed to the “packed” subfolder.
ActionView :: Helpers :: AssetTagHelper . register_javascript_expansion JAVASCRIPT_FILES
- allows the helper javascript_include_tag to connect several files with keys that are specified in js_files.yml.
Adding javascripts to the template
javascript_include_tag : base ,: cache => "base_packed"
: cache, when set, config.action_controller.perform_caching = true will give us one base_packed.js file, the contents of which will be all the files listed in: base.
Task to pack
Create lib / tasks / packr.rake file
require 'packr'
namespace : packr do
task : pack do
files = YAML :: load ( File . read ( "# {RAILS_ROOT} /config/js_files.yml" ) ) [ "base" ]
files. each do | file |
puts "# {file} packing ..."
File . open ( "# {RAILS_ROOT} / public / javascripts / packed / # {file}" , 'wb' ) do | f |
f. write ( Packr. pack ( File . read ( "# {RAILS_ROOT} / public / javascripts / # {file}" ) ,: shrink_vars => true ,: private => true ,: base62 => true ) )
end
puts "packed \ n \ n "
end
end
end
Just a few words about this code, here, in this case, only the files with the key “base” will be packed and put into the “javascripts / packed” folder, I will return to this at the end of the article.
So, everything is ready for packaging. But before that you need to create a javascripts / packed folder, otherwise you will get an error.
To run the packer run the command rake packr: pack. You will find the packaged files in the javascripts / packed created in advance.
Further improvements
First:
The scripts indicate the folder for the packed files, it is set in each script. For versatility, you should put it in a constant.
Second:
In the task, files are only packed from the key: base, here you should remove this parameter from the line
files = YAML :: load ( File . read ( "# {RAILS_ROOT} /config/js_files.yml" ) ) [ "base" ]
and make passes on all the keys. If necessary, add a parameter which key should be packaged.
Third:
Javascript source files are still in the public / javascripts folder, you need to move them, for example, to lib / javascripts, because in production, they are useless. In development, you can simply make a link from lib to public. In production in “public / javascripts”, add packed files, and the “packed” folder will not be needed. At the same time, the initializers / javascript_files.rb script will be simplified, since It will not be necessary to divide files into production and development.
Fourth:
Files must be packaged on the server, before restarting the server. If you use capistrano, you can do it, for example, as follows:
task : before_symlink do
run "mkdir -p # {release_path} / public / javascripts"
run "rake packr: pack"
end
Suggestions and comments are welcome.
Thanks for attention!