【问题标题】:Rails Asset Caching Breaks First few page loadsRails 资产缓存中断前几个页面加载
【发布时间】:2011-02-15 16:58:18
【问题描述】:

我们正在为 JS 和 CSS 使用 Rails 资产缓存,如下所示:

<%= 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) %>

在我们的部署中,我们每次都调用rake tmp:assets:clear。问题是部署后的前几个页面加载后页面上没有 css 或 js。我想直到缓存的 all.js 和 all.css 被重新生成。

我们每天部署多次,这对于碰巧遇到崩溃页面的任何用户来说都是可怕的。

人们有没有找到任何方法让这个过程更顺畅,从而保证新的缓存资产在第一个新页面加载时就在那里?

【问题讨论】:

  • 几个问题: 1) 你在不同的机器上有多个应用服务器吗? 2) 模板中 CSS 的缓存行是什么?
  • 嗨,斯科特。一台机器上的所有应用服务器。这是一个 css 缓存行的示例:&lt;%= stylesheet_link_tag 'reset','global','admins','autocomplete', 'date_input', 'tablesorter', 'partners', 'jqmodal', :media =&gt; 'screen', :cache =&gt; set_asset_cache(:admins) %&gt; 我们为管理员、买家、卖家、登录页面等设置了单独的缓存行(每个布局一个)。谢谢!

标签: ruby-on-rails caching assets


【解决方案1】:

AssetHat gem 解决了这个确切的问题。不是在第一次加载页面时连接资产(这会增加该页面的加载时间),而是在部署时连接资产。作为奖励,gem 还缩小了您的 CSS 和 JS,从而节省了宝贵的字节数。

设置后,使用非常简单:

  • 在您的布局中使用include_css :bundle =&gt; 'admins'include_js :bundle =&gt; 'admins'。 (捆绑内容在配置文件中设置,以保持您的布局轻量级。)
  • rake asset_hat:minify 添加到您的部署脚本中。我的公司已经在 Capistrano 的生产环境中使用它大约一年了。

readmedocs 中有更多信息,我很乐意听到任何问题/想法!

【讨论】:

    【解决方案2】:

    您可以尝试在部署期间使用 wget 预热缓存,例如 (shamelessly reposted):

    wget -r -nd --delete-after http://whatever.com/~popular/page/
    

    但是,这必须在您将符号链接切换到新部署后执行。一个可能更优雅的解决方案可能是在您的部署中手动调用资产缓存方法,尽管我不确定这是否可行。 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
    

    您也许可以修改缓存代码并在部署时手动运行它。

    【讨论】:

    • wget 可以工作,虽然我们的一些资产缓存只在登录页面上生成(一个用于管理员、买家、卖家等),所以我认为用户无法通过简单的方式登录wget。 write_asset_file_contents 方法看起来很有希望。如果有人在 capistrano 部署中工作,那会很有趣。
    猜你喜欢
    • 2012-03-02
    • 2015-10-15
    • 2014-07-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-15
    • 1970-01-01
    相关资源
    最近更新 更多