在Rails生产中,config.assets.compile = true,为什么不呢?

rails new安装的默认Rails应用程序在生产中有config.assets.compile = false

做事情的一般方法是运行rake assets:precompile在部署应用程序之前进行rake assets:precompile ,以确保编译所有资产管道资产。

那么,如果我在生产中设置config.assets.compile = true ,会发生什么?

我不会'需要再运行precompile 。 我相信会发生的第一次资产被请求,它将被编译。 这将是第一次的性能打击(这意味着你通常需要在生产中的js运行时才能做到这一点)。 但除了这些缺点之外,在资产被懒散地编译之后,我认为随后对该资产的所有访问将不会有性能影响,应用程序的性能将与预编译资源完全相同这是真的?

有什么我失踪? 任何其他原因,不要在生产中设置config.assets.compile = true ? 如果在生产环境中有一个JS运行库,并且愿意为了首次访问资产而牺牲性能下降的precompile ,那么为了不必运行precompile ,这是否有意义呢?

我写了那个指南的那一点。

你绝对不想在生产中编译。

当你编译时,会发生什么情况:

/ assets中的每个文件请求都被传递给Sprockets。 在每一个资产的第一个请求,它被编译和缓存在任何Rails用于缓存(通常是文件系统)。

在随后的请求中,Sprockets收到请求,并且必须查找指纹文件名,检查组成资源的文件(图像)或文件(css和js)是否未被修改,然后是否存在缓存的版本。

这是资产文件夹插件使用的任何供应商/资产文件夹中的所有内容。

这是一个很大的开销,说实话,代码没有为速度优化。

这将对资产通过网络传输到客户端的速度产生影响,并会对网站的网页加载时间产生负面影响。

与默认值相比较:

当资产被预编译并且编译关闭时,资产被编译并指纹给public/assets 。 Sprockets将普通文件到指纹文件的映射表返回给Rails,Rails将其写入文件系统。 清单文件(Rails 3中的YML或Rails 4中带有随机名称的JSON)在启动时由Rails加载到内存中,并由资产助手方法使用。

这使得生成具有正确指纹资源的页面非常快,并且文件本身的服务是快速的文件服务器。 两者都比现场编译速度快得多。

为了获得管道和指纹的最大优势,您需要在您的Web服务器上设置远期标题,并为js和css文件启用gzip压缩。 链轮写入gzip版本的资产,您可以设置您的服务器使用,无需为每个请求这样做。

这样可以尽可能快地将资产提供给客户端,并尽可能缩小客户端页面的显示速度,并减少(远期标题)请求。

所以如果你正在编译它是:

  1. 非常慢
  2. 缺乏压缩
  3. 会影响页面的呈现时间

  1. 尽可能快
  2. 压缩
  3. 从服务器上删除压缩(可选)。
  4. 尽量减少页面的渲染时间。

编辑:(回复跟进评论)

在第一个请求中, 可以将流水线更改为预编译,但是这样做有一些主要障碍。 首先是必须有指纹名称的查找表,否则辅助方法太慢。 在按需编译的情况下,当编译或请求每个新资产时,需要有一些方法来追加到查找表中。

另外,在所有的资产都编制完成之前,有人会不得不在不知道的时间内支付缓慢的资产交付的价格。

默认情况下,编译所有东西的价格一次性脱机支付,不会影响公众访问者,并确保所有东西都能正常工作。

这个交易断路器是为生产系统增加了很多复杂性。

[编辑,2015年6月]如果你正在阅读这个,因为你正在寻找解决方案,在部署过程中编译时间很慢,那么你可以考虑在本地预编译资产。 有关这方面的信息在资产管道指南中 。 这允许您仅在发生更改时进行本地预编译,然后进行提交,然后在没有预编译阶段的情况下进行快速部署。

用预编译的东西来减少开销。

 Precompile everything initially with these settings in production.rb # Precompile *all* assets, except those that start with underscore config.assets.precompile << /(^[^_\/]|\/[^_])[^\/]*$/ 

那么您可以简单地使用图像和样式表,如* .html.erb或“/assets/web.png”中的“/assets/stylesheet.css”

对于任何使用Heroku的人:

如果你部署到Herkou,它将在部署期间自动执行预编译,如果编译资产不包括(即public/assets未提交),所以不需要config.assets.compile = true或提交预编译资产。

Heroku的文档在这里 。 建议使用CDN来移除动态码资源上的负载。

设置config.asset.compile = false

添加到你的Gemfile

group :assets do gem 'turbo-sprockets-rails3' end

安装捆绑软件

运行rake assets:precompile

然后启动你的服务器

从官方指导 :

在第一个请求上,资源被编译和缓存,如上面开发中概述的,并且助手中使用的清单名称被改变以包括MD5哈希。

链轮还将Cache-Control HTTP标头设置为max-age = 31536000。 这表示服务器和客户端浏览器之间的所有缓存都可以缓存该内容(所提供的文件)1年。 这样做的效果是减少从您的服务器请求这个资产的数量; 该资产在本地浏览器缓存或一些中间缓存中有很好的机会。

此模式使用更多的内存,执行比默认值更差,不建议。

此外,如果您使用Capistrano进行部署,预编译步骤完全不是麻烦。 它为你照顾。 你只是跑步

 cap deploy 

或(取决于您的设置)

 cap production deploy 

你们都定了 如果您仍然不使用它,我强烈建议您检查一下。

即使在第一次打击之后,它也不会像预编译一样:因为这些文件没有写入文件系统,所以它们不能由Web服务器直接提供。 一些ruby代码将始终被涉及,即使它只是读取一个缓存条目。