We're using Rails asset caching for JS and CSS like this:
<%= stylesheet_link_tag 'reset','global','admins','autocomplete', 'date_input', 'tablesorter', 'partners', 'jqmodal', :media => 'screen', :cache => set_asset_cache(:admins) %>
<%= javascript_include_tag :defaults, 'autocomplete', 'searchbox', 'jqmodal', :cache => set_asset_cache(:admins) %>
In our deploy we call rake tmp:assets:clear
each time. The problem is that the first few page loads after a deploy come up with no css or js on the page. I guess until the cached all.js and all.css have been regenerated.
We deploy many times per day and this is scary for any users who happen to come across a busted page.
Have people found any way to make this smoother so the new cached assets are guaranteed to be there on the first new page load?
The AssetHat gem addresses this exact problem. Instead of concatenating assets the first time a page is loaded (which increases that page's load time), it concatenates assets on deploy instead. As a bonus, the gem also minifies your CSS and JS, which saves precious bytes.
After setup, usage is pretty simple:
include_css :bundle => 'admins'
and include_js :bundle => 'admins'
in your layout. (The bundle contents are set in a config file to keep your layout lightweight.)rake asset_hat:minify
to your deploy script. My company has been using it in production with Capistrano for about a year now.There's more info in the readme and docs, and I'd be happy to hear any questions/ideas!
You could try warming the cache during deployment using wget, as an example (shamelessly reposted):
wget -r -nd --delete-after http://whatever.com/~popular/page/
However, this would have to be executed after you switch your symlink to your new deployment. A possibly more elegant solution might be to call the asset caching methods manually in your deploy, though I'm not sure how feasible that is. Here's where the caching is performed in Rails:
# File vendor/rails/actionpack/lib/action_view/helpers/asset_tag_helper.rb, line 273
273: def javascript_include_tag(*sources)
274: options = sources.extract_options!.stringify_keys
275: concat = options.delete("concat")
276: cache = concat || options.delete("cache")
277: recursive = options.delete("recursive")
278:
279: if concat || (ActionController::Base.perform_caching && cache)
280: joined_javascript_name = (cache == true ? "all" : cache) + ".js"
281: joined_javascript_path = File.join(joined_javascript_name[/^#{File::SEPARATOR}/] ? ASSETS_DIR : JAVASCRIPTS_DIR, joined_javascript_name)
282:
283: unless ActionController::Base.perform_caching && File.exists?(joined_javascript_path)
284: write_asset_file_contents(joined_javascript_path, compute_javascript_paths(sources, recursive))
285: end
286: javascript_src_tag(joined_javascript_name, options)
287: else
288: expand_javascript_sources(sources, recursive).collect { |source| javascript_src_tag(source, options) }.join("\n")
289: end
290: end
You might be able to modify the caching code and run it manually on deploy.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With